c 11 – 为什么“矢量v {{5,6}};`工作?我以为只有一双{}被允许?

前端之家收集整理的这篇文章主要介绍了c 11 – 为什么“矢量v {{5,6}};`工作?我以为只有一双{}被允许?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
给定一个具有两个构造函数的类A,取initializer_list< int>和initializer_list< initializer_list< int>>分别
A v{5,6};

打电话给前者,和

A v{{5,6}};

呼吁后者,如预期. (clang3.3,显然gcc的行为有所不同,看到答案,标准要求什么?)

但是如果我删除第二个构造函数,那么A v {{5,6}};仍然编译,它使用第一个构造函数.我没想到这个
我认为A v {5,6}将是访问initializer_list< int>的唯一方法.构造函数.

(我在std :: vector和this question I asked on Reddit播放时发现了这一点,但是我创建了自己的A类,以确保它不仅仅是std :: vector的界面的怪癖.)

解决方法

我想这个 answer might be relevant.

Yes,this behavIoUr is intended,according to §13.3.1.7 Initialization
by list-initialization

When objects of non-aggregate class type T are list-initialized (8.5.4),overload resolution selects the constructor in two phases:

— Initially,the candidate functions are the initializer-list constructors (8.5.4) of the class T and the argument list consists of
the initializer list as a single argument.

— If no viable initializer-list constructor is found,overload resolution is performed again,where the candidate functions are all
the constructors of the class T and the argument list consists of the
elements of the initializer list.

在gcc我试过你的例子.我得到这个错误

error: call of overloaded 'A(<brace-enclosed initializer list>)' is ambiguous

如果我使用三套大括号,gcc会停止抱怨.即:

#include <iostream>
#include <vector>
#include <initializer_list>

struct A {
    A (std::initializer_list<int> il) { 
        std::cout << "First." << std::endl;
    }
    A (std::initializer_list<std::initializer_list<int>> il) { 
        std::cout << "Second." << std::endl;
    }
};

int main()
{
    A a{0}; // first
    A a{{0}}; // compile error
    A a2{{{0}}}; // second
    A a3{{{{0}}}}; // second
}

试图镜像向量的构造函数,这里是我的结果:

#include <iostream>
#include <vector>
#include <initializer_list>

struct A {
    A (std::initializer_list<int> il) { 
        std::cout << "First." << std::endl;
    }
    explicit A (std::size_t n) {
        std::cout << "Second." << std::endl;
    }
    A (std::size_t n,const int& val) {
        std::cout << "Third." << std::endl;
    }
    A (const A& x) {
        std::cout << "Fourth." << std::endl;
    }
};

int main()
{
    A a{0};
    A a2{{0}};
    A a3{1,2,3,4};
    A a4{{1,4}};
    A a5({1,4});
    A a6(0);
    A a7(0,1);
    A a8{0,1};
}

main.cpp:23:10: warning: braces around scalar initializer

    A a2{{0}};

         ^~~

1 warning generated.

First.
First.
First.
First.
First.
Second.
Third.
First.

猜你在找的C&C++相关文章