是否可以使用C ++ 11 initializer_list
使用Foo
构造函数汇编下面的constexpr
递归定义的类:
template <size_t N>
struct Foo {
constexpr Foo(int x, Foo<N-1> f) : x(x), xs(xs) {}
int x;
Foo<N-1> xs;
};
template <> struct Foo<0> {};
我可以使用
初始化Foo<3>
int main(int argc, char *argv[])
{
Foo<3> a = Foo<3>(1,Foo<2>(2,Foo<1>(3,Foo<0>())));
return 0;
}
使用Foo&lt; 3&gt;会很好。 a = {1,2,3}而不是。如果constexpr tail
中有initializer_list
函数,我认为它应该有用。
答案 0 :(得分:9)
是的,以一种循环方式,有效地解压缩并将初始化列表重新打包为更合适的格式。但是,有一种更好的(imho)方式:Variadic模板。
#include <stddef.h>
#include <iostream>
template <size_t N>
struct Foo {
template<class... Tail>
constexpr Foo(int i, Tail... t) : x(i), xs(t...) {}
void print(){
std::cout << "(" << x << ", ";
xs.print();
std::cout << ")";
}
int x;
Foo<N-1> xs;
};
template <>
struct Foo<1> {
constexpr Foo(int i) : x(i) {}
void print(){ std::cout << "(" << x << ")"; }
int x;
};
int main(){
Foo<3> x = {1, 2, 3};
x.print();
std::cout << "\n";
}
按预期输出:
(1,(2,(3)))
请注意,我选择1
作为基本情况,因为它更有意义。
答案 1 :(得分:1)
我没有可编译它的编译器,但我认为正确的答案是:
template <size_t N>
struct Foo {
constexpr Foo(int x, Foo<N-1> f) //template iterator constructor
: x(x), xs(xs) {}
Foo(std::initializer_list<int> f) //initializer list constructor
: x(*f.begin()), xs(++f.begin(), f.end())
{ static_assert(xs.size()==N, "incorrect number of values in initializer list");}
template<class iter>
Foo(iter first, iter last) //template iterator constructor
: x(*first), xs(++first, last) {} //UB if wrong number of values given
int x;
Foo<N-1> xs;
};
template <>
struct Foo<1> { //I use 1 for smaller structures
constexpr Foo(int f)
: x(f) {}
Foo(std::initializer_list<int> f)
: x(*f.begin())
{ static_assert(xs.size()==1, "incorrect number of values in initializer list");}
template<class iter>
Foo(iter first, iter last)
: x(*first)
{ assert(first+1 == last); }
int x;
};
对于递归结构,初始化程序列表必须以递归方式传递给接收迭代器的构造函数。
答案 2 :(得分:0)
解决方案是创建一个名为
的函数template<class T>
constexpr T initlist_val(initializer_list<T>& list, int index) {
return (index < list.size()) ? *(list.begin() + index) : 0;
}
现在你可以去
了class MyClass {
public:
int A, int B;
constexpr MyClass(const initializer_list<int>& list) : A(initlist_val(list,0)), B(initlist_val(1)) {
// Put nothing here etc..
}
};
你不需要所有其他的东西。这可以与未经其他任何测试的GCC一起使用。可能在规则方面不正确。