不确定如何对此问题或搜索内容进行说明,如果这与其他问题相同,请关闭并重定向到相应的问题。
假设
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功能的解决方案很好。
答案 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.