当前位置: 首页 > 知识库问答 >
问题:

如何根据initializer\u列表的大小导致编译时错误?

孟晨朗
2023-03-14

如果我有一个简单的结构

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;
}

现在,我希望在初始化点时有相同的行为,点成为类,但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_assertinitializer_list::size()
  • 为什么size不是std::initializer_list的模板参数?

通过阅读答案和评论,我理解了一些constexrstatic_assert问题,但仍然没有找到解决我问题的方法。是否有可能在C 11(或C 14)中导致编译时错误?编译器肯定知道它需要的所有信息,并且对于某人来说,似乎有足够的可能要做的事情是标准会以某种方式将其卷进来。

共有2个答案

时向文
2023-03-14

没有编译时方法来检索std::initializer_list大小,但您不需要它。

类似于初始值设定项的语法被命名为统一初始化,这是c 11的一部分,以统一语法,作为名称自定义。

这里有一个适用于您的观点的完整示例,如您所见,带有参数的构造函数可以与初始值设定项列表匹配。

#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
}
曹驰
2023-03-14

通过将初始值设定项列表构造函数替换为如下所示的构造函数。。。

Point(int x, int y) :m_x(x), m_y(y) {}

注意,我将私有变量x和y重写为m_x和m_y。

现在,当您尝试初始化具有多个参数的Point对象时,您将得到一个类似于Point是结构时的编译器错误。

 类似资料:
  • 我试图用C(11/14)实现fortran的重塑功能,并设计了一个函数。此函数接受两个std::initializer\u列表。第一个initializer\u列表给出了我用来初始化多维数组的初始值。第二个initializer\u列表给出了数组每个维度的大小。我写了一份这样的草稿 这个实现需要给定的非类型模板参数int D,但我想要不带D的东西,比如重塑({1,2,3,4,5,6},{2,3})

  • 刚接触C语言的我,正试图了解initializer\u list。 我正在制作一个Matrix类,它有效地存储了一个双值的二维数组。我没有在结构层面上得到这个项目。就像好吧,我们制作了一个Matrix类,它本质上存储了一个2D数据数组。但是它需要能够存储任何大小的数组,所以它必须使用动态分配的数组。但是std::array是不允许的。 我不知道如何访问i_list中的项目。如果它们像 然后根据我看

  • 问题内容: 我正在努力寻找合适的措词来回答我的问题(这可能就是为什么我无法使用Google),但归结为:为什么下面的行无效? 我收到了一个编译时错误。班级和班级。 我已经阅读了有关泛型的Oracle文档,但显然这里缺少一些关键之处。朝正确方向轻推将不胜感激! 问题答案: 今天早些时候,我认为您想成为的数据类型。当然,这是将与您创建的对象匹配的数据类型,但是我怀疑在这种情况下它是否真的是您想要的。请

  • 问题内容: 对于这两个进口; 我收到此错误: 如何解决此错误? 问题答案: 该错误是由您的Eclipse配置引起的。您可以将其减少为警告。更好的是,使用不属于非公共API的Base64编码器。Apache Commons有一个,或者当您已经使用Java 1.8时,请使用。

  • 在下面的代码中,我展示了类似联合的类S,它包含两个不相关的结构B和C。我展示了如何实例化非POD std::字符串并再次删除它,然后将S切换到S::CC 并设置num int。 然而,我的目标是在std::initializer\u列表中使用S。我不知道初始化h的格式应该是什么。如果我想用这些S::BB,S::CC,S::BB初始化h,参数应该是什么? 我的编译器是VS2015。 编辑:这篇文章的

  • 我有一个java应用程序-一个计算器。我想通过调整应用程序窗口的大小来动态调整按钮的字体大小。如何实现? 我的想法是使用ComponentEvents。我有应用程序窗口的初始大小和初始字体的大小。我想根据按钮的大小改变字体大小,受窗口大小变化的影响。问题是如何在覆盖方法中使用比例[初始窗口大小]/[初始字体大小]?每个字体的比例都不同。