仅当给出超过 n 个参数时,我如何 enable_if 可变参数模板构造函数?
How do I enable_if a variadic template constructor only if more than n arguments are given?
我有一个 class 具有以下构造函数:
template<typename T>
class MyClass {
public:
MyClass() = default;
explicit MyClass(T val) : value_1(val) { /* ... */ }
explicit MyClass(T val, T val2) : value_1(val), value_2(val2) { /* ... */}
private:
T value_1 = 0;
T value_2 = 0;
};
我还想创建一个构造函数,它接受任意数量的参数(所有参数都可以是 T
)。构造函数也不能隐藏我已经编写的其他构造函数,因为完成的工作是不同的。我尝试了 enable_if
一点点,但我无法让它工作。这是我目前所拥有的:
template<typename... TArgs>
explicit MyClass(TArgs... mArgs, typename std::enable_if<sizeof...(mArgs) >= 3>) { /* ... */ }
然而,当这样调用时:
MyClass<double>(2, 3, 4, 5, 6, 7);
它产生了这个错误(以及其他错误):
error: no matching function for call to 'MyClass<double>::MyClass(int, int, int, int, int, int)'
因此编译器可能甚至看不到构造函数。另一方面,如果我只是省略 enable_if
,它永远不会调用我的其他更专业的构造函数。
简而言之,当且仅当 为构造函数提供了三个或更多参数时,我如何才能调用可变参数构造函数?
编辑:
根据评论中的建议,我现在也尝试了以下方法,但也不起作用:
template<typename... TArgs>
explicit MyClass(TArgs... mArgs, typename std::enable_if<sizeof...(mArgs) >= 3>::type) { /* ... */ }
以及
template<typename... TArgs>
explicit MyClass(TArgs... mArgs, typename std::enable_if<sizeof...(mArgs) >= 3>* = nullptr) { /* ... */ }
或两者的任意组合。
建议:试试
template <typename... TArgs,
typename = typename std::enable_if<sizeof...(TArgs) >= 3>::type>
explicit MyClass(TArgs... mArgs) { /* ... */ }
或更好(以避免与具有相同签名的多个启用 SFINAE 的构造函数发生冲突)。
template <typename... TArgs,
typename std::enable_if<sizeof...(TArgs) >= 3, bool>::type = true>
explicit MyClass(TArgs... mArgs) { /* ... */ }
你的原始代码有问题
template<typename... TArgs>
explicit MyClass(TArgs... mArgs, typename std::enable_if<sizeof...(mArgs) >= 3>::type) { /* ... */ }
只有当相对参数位于最后位置时,您才能推导出可变类型列表。
如果再添加一个参数
typename std::enable_if<sizeof...(mArgs) >= 3>::type
您打破了 TArgs...
类型的推导。
我有一个 class 具有以下构造函数:
template<typename T>
class MyClass {
public:
MyClass() = default;
explicit MyClass(T val) : value_1(val) { /* ... */ }
explicit MyClass(T val, T val2) : value_1(val), value_2(val2) { /* ... */}
private:
T value_1 = 0;
T value_2 = 0;
};
我还想创建一个构造函数,它接受任意数量的参数(所有参数都可以是 T
)。构造函数也不能隐藏我已经编写的其他构造函数,因为完成的工作是不同的。我尝试了 enable_if
一点点,但我无法让它工作。这是我目前所拥有的:
template<typename... TArgs>
explicit MyClass(TArgs... mArgs, typename std::enable_if<sizeof...(mArgs) >= 3>) { /* ... */ }
然而,当这样调用时:
MyClass<double>(2, 3, 4, 5, 6, 7);
它产生了这个错误(以及其他错误):
error: no matching function for call to 'MyClass<double>::MyClass(int, int, int, int, int, int)'
因此编译器可能甚至看不到构造函数。另一方面,如果我只是省略 enable_if
,它永远不会调用我的其他更专业的构造函数。
简而言之,当且仅当 为构造函数提供了三个或更多参数时,我如何才能调用可变参数构造函数?
编辑:
根据评论中的建议,我现在也尝试了以下方法,但也不起作用:
template<typename... TArgs>
explicit MyClass(TArgs... mArgs, typename std::enable_if<sizeof...(mArgs) >= 3>::type) { /* ... */ }
以及
template<typename... TArgs>
explicit MyClass(TArgs... mArgs, typename std::enable_if<sizeof...(mArgs) >= 3>* = nullptr) { /* ... */ }
或两者的任意组合。
建议:试试
template <typename... TArgs,
typename = typename std::enable_if<sizeof...(TArgs) >= 3>::type>
explicit MyClass(TArgs... mArgs) { /* ... */ }
或更好(以避免与具有相同签名的多个启用 SFINAE 的构造函数发生冲突)。
template <typename... TArgs,
typename std::enable_if<sizeof...(TArgs) >= 3, bool>::type = true>
explicit MyClass(TArgs... mArgs) { /* ... */ }
你的原始代码有问题
template<typename... TArgs>
explicit MyClass(TArgs... mArgs, typename std::enable_if<sizeof...(mArgs) >= 3>::type) { /* ... */ }
只有当相对参数位于最后位置时,您才能推导出可变类型列表。
如果再添加一个参数
typename std::enable_if<sizeof...(mArgs) >= 3>::type
您打破了 TArgs...
类型的推导。