如果我有一个简单的结构
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;
};它可以工作,但会将编译时错误更改为运行时错误。现在的问题是:如何使该类的行为与简单的结构相同,即在初始化程序列表太大时导致编译时错误?
环顾四周我发现
通过阅读答案和评论,我理解了一些constexpr和static_assert问题,但仍然没有找到解决我问题的方法。在C++11 (或C++14)中有可能导致编译时错误吗?编译器肯定知道它需要做的所有事情,而且对于想要这样做的人来说,这似乎是一件很有可能的事情,标准会在某种程度上将它滚动进去。
发布于 2015-01-16 11:10:57
将初始化程序列表构造函数替换为如下所示的构造函数.
Point(int x, int y) :m_x(x), m_y(y) {}注意,我将私有变量x和y重写为m_x和m_y。
现在,当您尝试用两个以上的参数初始化Point对象时,您将得到一个编译器错误,类似于Point是一个结构时的错误。
发布于 2015-01-17 01:54:24
没有检索std::initializer_list大小的编译时方法,但您不需要它。
初始化器类似于语法,名为统一初始化,是c++11的一部分,以统一名称自定义的语法。
这里有一个为您的Point工作的完整示例,正如您可以看到的那样,带有参数的构造函数可以与初始化程序列表匹配。
#include <iostream>
class Point {
public:
Point() = default;
Point( int x, int y ) : x_{x}, y_{y} {}
Point( int x ) : x_(x) {}
// or in your case, you can use a default argument
//Point( int x, int y = int{} ) : x_{x}, y_{y} {}
int X() const { return x_; }
int Y() const { return y_; }
private:
int x_{};
int y_{};
};
void DisplayPoint( Point const & p) {
std::cout << "( " << p.X() << ", " << p.Y() << " )" << std::endl;
}
Point GetAPoint() {
return { 3, 5 };
}
int main() {
DisplayPoint( {} );
DisplayPoint( { 1 } );
DisplayPoint( { 1, 2 } );
DisplayPoint( GetAPoint() );
DisplayPoint( Point( 5, 3 ) ); // pre c++11
DisplayPoint( Point{ 5, 3 } ); // in the case the constructor is explicit
}https://stackoverflow.com/questions/27982251
复制相似问题