代码之家  ›  专栏  ›  技术社区  ›  peterchen

常量作为模板参数

  •  12
  • peterchen  · 技术社区  · 14 年前

      // ----- non-const -----
      struct arg_adapter
      {
          EArgType type;  // fmtA, fmtB, ...
    
          union
          {
            TypeA * valueA;
            TypeB * valueB;
            // ... more types
          }
    
          arg_adapter(TypeA & value) : type(fmtA), valueA(&value) {}
          arg_adapter(TypeB & value) : type(fmtB), valueB(&value) {}
          // ...
      }
    
      // ----- const version -----
      struct const_arg_adapter
      {
          EArgType type;  // fmtA, fmtB, ...
    
          union
          {
            TypeA const * valueA;
            TypeB const * valueB;
            // ... more types
          }
    
          arg_adapter(TypeA const & value) : type(fmtA), valueA(&value) {}
          arg_adapter(TypeB const & value) : type(fmtB), valueB(&value) {}
          // ...
      }
    

    它们应用于以下方法:

      Convert(const_arg_adapter from, arg_adapter to)
    

    现在我的问题;-)

    我的目标是只维护一个结构,即。

    template <Qualifier CONSTNESS>
    struct arg_adapter_t
    {
       ...
       CONSTNESS TypeA * valueA;
       ...
    }
    
    3 回复  |  直到 14 年前
        1
  •  7
  •   Johannes Schaub - litb    14 年前

    你可以让它接受 metafunction 你可以应用任何你喜欢的变换

    template<template<typename> class F>
    struct arg_adapter
    {
        EArgType type;  // fmtA, fmtB, ...
    
        union
        {
          typename F<TypeA>::type * valueA;
          typename F<TypeB>::type * valueB;
          // ... more types
        };
    
        arg_adapter(typename F<TypeA>::type & value) : type(fmtA), valueA(&value) {}
        arg_adapter(typename F<TypeB>::type & value) : type(fmtB), valueB(&value) {}
        // ...
    };
    
    typename arg_adapter<boost::add_const> const_adapter;
    typename arg_adapter<boost::mpl::identity> nonconst_adapter;
    

    metafunction class 获得更大的灵活性(包括 F arg_adapter 诸如此类。

    template<typename F>
    struct arg_adapter
    {
        EArgType type;  // fmtA, fmtB, ...
    
        union
        {
          typename apply<F, TypeA>::type * valueA;
          typename apply<F, TypeB>::type * valueB;
          // ... more types
        };
    
        arg_adapter(typename apply<F, TypeA>::type & value) : type(fmtA), valueA(&value) {}
        arg_adapter(typename apply<F, TypeB>::type & value) : type(fmtB), valueB(&value) {}
        // ...
    };
    
    typename arg_adapter< lambda< boost::add_const<_> >::type > const_adapter;
    typename arg_adapter< lambda< boost::mpl::identity<_> >::type > nonconst_adapter;
    
        2
  •  8
  •   Danvil    14 年前

    这是类型选择器:

    template<bool flag, typename T, typename U>
    struct Select { typedef T Result; }
    
    template<typename T, typename U>
    struct Select<false, T, U> { typedef U Result; }
    

    你的班级看起来是这样的:

    template<bool isConst>
    struct arg_adapter
    {
      // define A and B as const or non-const
      typedef typename Select<isConst, const TypeA, TypeA>::Result A;
      typedef typename Select<isConst, const TypeB, TypeB>::Result B;
    
      EArgType type;  // fmtA, fmtB, ...
    
      union
      {
        A * valueA; // this is either const TypeA* oder TypeA* depending on
                    // your choice of the isConst template parameter
        B * valueB;
        // ... more types
      }
    
      arg_adapter(A & value) : type(fmtA), valueA(&value) {} // same here with ref
      arg_adapter(B & value) : type(fmtB), valueB(&value) {}
      // ...
    }
    

    为了方便起见,可以使用typedef:

    struct nonconst_adapter : public arg_adapter<false> {};
    
    struct const_adapter : public arg_adapter<true> {};
    

    这是我以前用简单的类型特征得出的答案:

    template<typename TypeTraits>
    struct arg_adapter
    {
      typedef typename TypeTraits::T T;
      void bar(T a) { ... } // by value/reference
      void bar(T* a) { ... } // by pointer
    }
    
    template<typename K>
    struct NonConstTraits {
      typedef K T;
    }
    
    template<typename K>
    struct ConstTraits {
      typedef const K T;
    }
    
    template<typename K>
    struct nonconst_adapter : public arg_adapter<NonConstTraits<K> > {};
    
    template<typename K>
    struct const_adapter : public arg_adapter<ConstTraits<K> > {};
    
        3
  •  0
  •   Gobra    14 年前

    也许我没拿到,但你为什么不能用

    Convert(**const** arg_adapter from, arg_adapter to)
    

    声明typedef以简化作业

    推荐文章
    elee7311  ·  限定符VBA无效
    7 年前