【发布时间】:2015-03-14 22:58:08
【问题描述】:
如果我有一个像这样的简单结构
struct Point { int x, y; };
那我就可以了
int main()
{
Point p1 = { 10 }; // x = 10, y = 0
Point p2 = { 10, 20 }; // x = 10, y = 20
Point p3 = { 10, 20, 30 }; // Compile error: too many initializers for ‘Point’
return 0;
}
我现在希望在初始化 Point 时具有相同的行为,Point 成为一个类,但 x 和 y 成为私有并使用访问器等。
我的第一次尝试是
class Point
{
public:
Point( std::initializer_list<int> init )
{
switch( init.size() )
{
case 0: x = 0; y = 0; break;
case 1:
{
auto iter = init.begin();
x = *iter++; y = 0;
break;
}
case 2:
{
auto iter = init.begin();
x = *iter++; y = *iter++;
break;
}
default:
throw 0;
break;
}
}
private:
int x, y;
};
这有点工作,但将编译时错误更改为运行时错误。现在的问题是:如何使这个类的行为与简单结构相同,即当初始化列表太大时导致编译时错误?
环顾四周,我发现
- static_assert on initializer_list::size()
- Why is the size not a template argument of std::initializer_list?
通读答案和 cmets,我了解了一些 constexpr 和 static_assert 问题,但仍然无法找到解决我问题的方法。是否有可能在 C++11(或 C++14)中导致编译时错误?编译器肯定知道它需要做的所有事情,而且对于有人想要做的事情来说,标准可能会以某种方式将其引入。
【问题讨论】:
-
为什么使用 std::initializer_list 来初始化非容器成员?在您的情况下是否有必要从列表/结构文字初始化结构?
-
上面的代码是一个简单的玩具示例,试图说明“如何根据 initializer_list 的大小在编译时出错?”这个问题。实际使用是/将在由少量(基于目标硬件平台已知的编译时间)内存支持的容器类中。然后在编译时使用大括号初始化器填充这些内存块。代码正在从类 C 接口转换为 C++ 风格。可悲的是,我无法分享实际代码:(