c++ - 如何参数化构造函数的参数个数?

标签 c++ templates c++11 constructor

我想在模板类构造函数中接受最多多个参数(这个数字在模板参数中定义)。我不能使用 initializer_list ,因为据我所知,我无法在编译时断言它的大小。

我尝试了什么

我的第一次尝试是使用 std::array 作为参数:

template<size_t s>
class foo {
  int v[s];
public:
  foo(std::array<int, s>) {/*...*/}
};

但是,这迫使我像这样初始化(即使构造函数不是 explicit ):

foo<4> a{{1,2,3,4}} // Two brackets.

我认为可能有一些模板魔法(可变模板?),但我什至无法找出在构造函数中使用的正确语法。我不能递归调用构造函数……可以吗?

我试着寻找 std::array 的构造函数定义(因为它不允许超过数组大小的参数,这正是我想要的),但我所能找到的只是它具有隐式构造函数。那是默认构造函数吗?如果是这样,如何

std::array<int, 3> a = {1,2,3}

工作?

可选奖励:为什么标准没有定义 std::initializer_list 的固定大小替代方案? ?类似于 std::static_initializer_list<T, N> . future 是否有支持此类功能的计划?甚至需要它吗?

最佳答案

你可以创建一个可变参数构造函数,然后断言它提供了正确数量的参数:

template <size_t SZ>
struct Foo {
    template <typename... Args>
    Foo(Args... args) {
        static_assert(sizeof...(Args) <= SZ, "Invalid number of arguments");
        // ... stuff ...
    }
};

这样:

Foo<3> f;                // OK
Foo<3> f(1, 2, 3);       // OK
Foo<3> f(1, 2, 3, 4, 5); // error

作为初始化数组的示例,它可能如下所示:

template <size_t SZ>
struct Foo {
    template <typename... Args>
    Foo(Args... args) 
    : v{{args...}}
    {
        static_assert(sizeof...(Args) <= SZ, "Invalid number of arguments");
    }

    std::array<int, SZ> v;
};

如您所料,这会正确构造 v,但如果您尝试将超过 SZ 的参数传递给 Foo 的构造函数,您会在 static_assert 之前看到初始化 v 的错误。

对于更清晰的 static_assert 错误,您可以将顶级 Foo 委托(delegate)给私有(private)构造函数,这些构造函数采用额外的 integral_constant 参数来判断是否或不是他们是有效的构造函数:

template <typename... Args>
Foo(Args... args)
: Foo(std::integral_constant<bool, sizeof...(Args) <= SZ>{}, 
      args...)
{ }

private:
template <typename... Args>
Foo(std::true_type, Args... args)
: v{{args...}}
{ }

template <typename False, typename... Args>
Foo(False, Args... )
{ 
    // False is only ever std::false_type
    static_assert(False::value, "Invalid number of arguments!");
}

关于c++ - 如何参数化构造函数的参数个数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30925553/

相关文章:

c++ - 单字节字符代码

c++ - 有更好的方法来实现这个

控件模板中的 WPF 嵌套绑定(bind)

c++ - 从 C++11 中的容器元组中提取 value_type 的元组

c++ - 如何在 c++1y 的返回类型推导中保留 cv 限定符或引用?

c++ - 提示输入 CreateFile 的凭据

c++ - 递归函数中的boost regex smatch表现得像一个静态变量

c++ - 为什么以后不能在模板函数中添加默认参数?

c++ - 编码接受来自未指定来源的随机位的密码算法

c++ - std::pair 是否存在类似 std::tie 的东西?