Cás*_*nan 11 c++ templates constructor c++11
我想在模板类构造函数中接受多个参数(此数字在模板参数中定义).我不能使用initializer_list,因为据我所知,我无法在编译时断言它的大小.
我的第一次尝试是使用std :: array作为参数:
template<size_t s>
class foo {
int v[s];
public:
foo(std::array<int, s>) {/*...*/}
};
Run Code Online (Sandbox Code Playgroud)
但是,这迫使我像这样初始化(即使构造函数不是这样explicit):
foo<4> a{{1,2,3,4}} // Two brackets.
Run Code Online (Sandbox Code Playgroud)
我认为可能有一些模板魔术(可变参数模板?),但我甚至无法弄清楚在构造函数中使用的正确语法.我不能递归地调用构造函数...可以吗?
我试图寻找构造函数的定义std::array(因为它不允许比数组大小更多的参数,只是我想要的),但我能找到的只是它有隐式构造函数.这是默认的构造函数吗?如果是这样,怎么做
std::array<int, 3> a = {1,2,3}
Run Code Online (Sandbox Code Playgroud)
工作?
可选奖励:为什么标准没有定义固定尺寸替代std::initializer_list?有点像std::static_initializer_list<T, N>.是否有计划在未来支持此类功能?它甚至需要吗?
Bar*_*rry 10
您可以创建一个可变参数构造函数,并断言它提供了正确数量的参数:
template <size_t SZ>
struct Foo {
template <typename... Args>
Foo(Args... args) {
static_assert(sizeof...(Args) <= SZ, "Invalid number of arguments");
// ... stuff ...
}
};
Run Code Online (Sandbox Code Playgroud)
以便:
Foo<3> f; // OK
Foo<3> f(1, 2, 3); // OK
Foo<3> f(1, 2, 3, 4, 5); // error
Run Code Online (Sandbox Code Playgroud)
作为初始化数组的示例,可能如下所示:
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;
};
Run Code Online (Sandbox Code Playgroud)
v正如你所期望的那样构造正确,但如果你试图将SZargs 传递给Foo构造函数,你会看到在初始化v之前的错误static_assert.
为了更明确的static_assert错误,您可以将顶级委托Foo给私有构造函数,这些构造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!");
}
Run Code Online (Sandbox Code Playgroud)