简体   繁体   English

仅在给定n个以上参数的情况下,才能启用可变参数模板构造函数?

[英]How do I enable_if a variadic template constructor only if more than n arguments are given?

I have a class with the following constructors: 我有一个带有以下构造函数的类:

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;
};

I also want to create a constructor that takes an arbitrary number of arguments (all of which can be T 's). 我还想创建一个构造函数,该构造函数接受任意数量的参数(所有参数都可以是T )。 The constructor also mustn't shadow the other constructors I already wrote, as the work done is different. 构造函数也不能遮蔽我已经编写的其他构造函数,因为完成的工作是不同的。 I tried around with enable_if a little bit, but am unable to get this to work. 我尝试了一点enable_if ,但无法使其正常工作。 Here is what I have so far: 这是我到目前为止的内容:

template<typename... TArgs>
explicit MyClass(TArgs... mArgs, typename std::enable_if<sizeof...(mArgs) >= 3>) { /* ... */ }

However, when called like this: 但是,当这样调用时:

MyClass<double>(2, 3, 4, 5, 6, 7);

it yields this error (among others): 它会产生此错误(以及其他错误):

error: no matching function for call to 'MyClass<double>::MyClass(int, int, int, int, int, int)'

So the compiler probably doesn't even see the constructor. 因此,编译器甚至可能看不到构造函数。 On the other hand if I just leave out the enable_if , it will never call my other, more specialized constructors. 另一方面,如果我只剩下enable_if ,它将永远不会调用其他更专门的构造函数。

In short, how do I make it so the variadic constructor is called if and only if there are three or more arguments given to the constructor? 简而言之, 当且仅当给构造函数提供三个或更多参数时,如何才能使可变参数构造函数被调用?

EDIT: 编辑:

As proposed in the comments, I have now also tried the following, which also does not work: 正如评论中所建议的那样,我现在也尝试了以下方法,但这些方法也不起作用:

template<typename... TArgs>
explicit MyClass(TArgs... mArgs, typename std::enable_if<sizeof...(mArgs) >= 3>::type) { /* ... */ }

as well as 以及

template<typename... TArgs>
explicit MyClass(TArgs... mArgs, typename std::enable_if<sizeof...(mArgs) >= 3>* = nullptr) { /* ... */ }

or any combination of the two. 或两者的任何组合。

Suggestion: try with 意见建议:尝试一下

template <typename... TArgs,
          typename = typename std::enable_if<sizeof...(TArgs) >= 3>::type>
explicit MyClass(TArgs... mArgs) { /* ... */ }

or better (to avoid collisions with multiple SFINAE enabled constructors with the same signature). 或更好(以避免与具有相同签名的多个启用SFINAE的构造函数发生冲突)。

template <typename... TArgs,
          typename std::enable_if<sizeof...(TArgs) >= 3, bool>::type = true>
explicit MyClass(TArgs... mArgs) { /* ... */ }

The problem with your original code 您原始代码的问题

template<typename... TArgs>
explicit MyClass(TArgs... mArgs, typename std::enable_if<sizeof...(mArgs) >= 3>::type) { /* ... */ }

is that you can deduce a variadic list of types only if the relative arguments are in last position. 是只有在相对参数位于最后一个位置时,您才能推断出可变的类型列表。

If you add another argument 如果添加另一个参数

typename std::enable_if<sizeof...(mArgs) >= 3>::type

you break the deduction for the TArgs... types. 您打破了TArgs...类型的推论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM