具有整数模板参数指定的参数数量的类方法

时间:2010-07-15 15:32:35

标签: c++ templates oop c++11

不确定如何对此问题或搜索内容进行说明,如果这与其他问题相同,请关闭并重定向到相应的问题。

假设

template<typename Type, int Size> class vector
{
  Type data[Size];
}

是否可以替换在模板特化中使用大小数量的参数的构造函数,例如

template<typename Type> class vector3<Type,3>
{
  Type data[3];
  public:
    vector3( Type, Type, Type );
}

在非专业模板类中有什么东西?就像一个“varargs构造函数”,它生成一个构造函数,其大小数量类型为Type?

涉及C ++ 0x功能的解决方案很好。

4 个答案:

答案 0 :(得分:6)

在C ++ 0x中,template typedef终于可用了!

免责声明:没有编译任何内容......

来自维基百科的文章:

template< typename second>
using TypedefName = SomeType<OtherType, second, 5>;

在你的情况下会产生

template <class Type>
using vector3 = vector<Type, 3>;

我无法告诉你我对此有多渴望;)

但是它没有解决参数问题。如前所述,您可以尝试使用可变参数模板,但我不确定它们在这种情况下的应用。正常使用是使用递归方法,你需要在中间抛出static_assert

已编辑以考虑评论。

template <class Type, size_t Size>
class vector
{
public:
  template <class... Args>
  vector(Args... args): data({args...})
  {
    // Necessary only if you wish to ensure that the exact number of args
    // is passed, otherwise there could be less than requested
    BOOST_MPL_ASSERT_RELATION(sizeof...(Args), ==, Size);
  }

private:
  T data[Size];
};

现有的另一种可能性是将预处理器生成与boost::enable_if组合在一起。

template <class Type, size_t Size>
class vector
{
public:
  vector(Type a0, typename boost::enable_if_c< Size == 1 >::type* = 0);
  vector(Type a0, Type a1, typename boost::enable_if_c< Size == 2 >::type* = 0);
  // ...
};

使用Boost.Preprocessor进行生成使这更容易。

BOOST_PP_REPEAT(MAX_COUNT, CONSTRUCTOR_MACRO, ~);

// where MAX_COUNT is defined to the maximum size you wish
// and CONSTRUCTOR_MACRO actually generates the constructor

#define CONSTRUCTOR_MACRO(z, n, data)                              \
  vector(                                                          \
    BOOST_PP_ENUM_PARAMS(n, Type a),                               \
    typename boost::enable_if_c< Size == n >::type* = 0            \
  );

构造函数的实现留给读者练习。这是对BOOST_PP_REPEAT的另一次调用。

正如您所看到的,它很快变得难看,所以如果您可以使用可变参数模板版本,那么您将会变得更好。

答案 1 :(得分:3)

您的问题还有一个解决方案:在初始化列表中使用可变参数模板参数

template<typename T, unsigned int N>
struct vector {
    T data[N];

    template<typename... Args>
    vector(Args... args) : data({args...}) { }
};

但是,参数的数量只需要小于或等于N,并且它们的类型只需要转换为T

答案 2 :(得分:2)

  

是否可以替换在模板特化中使用大小数量的参数的构造函数,例如

并非没有大量重复的机械代码,并且最大尺寸将受到您重复自己的次数的限制。例证:boost::tuple(可能具有您想要的功能)。

在C ++ 0x中,由于variadic templates,这不会有问题。

答案 3 :(得分:2)

首先,您应该考虑使用std::array。它不能满足您的所有要求,但它足够接近,如果差异无关紧要,您可以为自己节省大量的工作。问题是这个便宜的版本将具有接受2个参数以及3的构造。

template< typename T>
using Vector3 = std::array<T,3>;

Vector3 v1{1,2,3};
Vector3 v2{1,2}; // it sounds like you want to disallow this case.

否则,您可以创建一个与std::array非常相似的自定义类,除非有更挑剔的构造函数。

template<typename T, std::size_t SIZE>
class Vector
{
public:
   template< typename ... Args >
   Vector( Args ... args ) :
      data({args...})
   {
      static_assert( sizeof...(Args) == SIZE,
                     "Incorrect number of arguments passed to Vector constructor");
   }
   /* lots of extra code here to add std::array -like methods */
private:
   // could use std::array here as well.
   T data[3];
};

template< typename T >
using Vector3 = Vector<T,3>;

Vector3 v1(1,2,3);
Vector3 v2(1,2); // error at compile time.