【问题标题】:Variadic arguments (with a pack size of N) and a default argument可变参数(包大小为 N)和默认参数
【发布时间】:2014-12-06 14:39:48
【问题描述】:

N 成为std::size_t 类型的模板参数。我希望能够以两种方式调用我的类的构造函数:

A a(x1, x2, x3, ..., xN)

A a(x1, x2, x3, ..., xN, xN1)

其中xi 变量都是同一类型。我的第一个想法是:

template <std::size_t N>
struct A
{
     template <typename ...Args, typename = typename std::enable_if<N == sizeof...(Args), void>::type>
     A(Args ...args) {
         f(args...); // where f is some function
     }

     template <typename ...Args, typename = typename std::enable_if<N+1 == sizeof...(Args), void>::type>
     A(Args ...args) {
         // run f on the first N arguments
         // run g on the last argument (selection is done using templates, I just did not want to write the code)
     }
};

此技术在以下位置进行了说明:Variadic templates with exactly n parameters。 当然,这样做的问题是不能以这种方式重载构造函数。

有什么想法吗?

【问题讨论】:

    标签: c++ templates c++11 metaprogramming template-meta-programming


    【解决方案1】:

    只是 SFINAE 不同:

    template <std::size_t N>
    struct A
    {
         template <typename ...Args, 
                   typename std::enable_if<N == sizeof...(Args), int>::type = 0>
         A(Args ...args) {
         }
    
         template <typename ...Args, 
                   typename std::enable_if<N+1 == sizeof...(Args), int>::type = 0>
         A(Args ...args) {
         }
    };
    

    Demo.

    【讨论】:

    • 你能解释一下区别吗?
    • @0x499602D2 OP 中的那个重新定义了相同的函数模板(具有不同的默认参数)。使enable_if 成为签名的一部分,使这两个不同的函数模板。
    • 那么前者应该用于 SFINAE 吗?
    • 一般来说两者都很好。如果重载具有完全相同的签名,则不能使用第一个。