2017-04-17 69 views
2

我有一个快速的示例:C++ 11:编译器何时将{}视为std :: initializer_list,何时不会?

#include <utility> 

using namespace std; 

struct A{ 
    int i; 
    char c; 
}; 

void f(const A&){} 

template<class T> 
void g(T&& t) 
{ 
    f(forward<T>(t)); 
} 

int main() { 
    A a={1,'@'};//OK 
    f({1,'#'});//OK 
    g({1,'@'});//Compilation error 
    return 0; 
} 

锵会给这个错误:

 
    testArray.cpp:16:5: error: no matching function for call to 'g' 
     g({1,'@'});//fix: g<A>({1,'@'}) 
     ^
    testArray.cpp:9:6: note: candidate template ignored: couldn't infer 
      template argument 'T' 
    void g(T&& t) 
     ^

我的问题是:

  1. A a={1,'@'};,如果{}推导为std::initializer_list那么它是如何从std::initilizer_list转换为A

  2. f({1,'#'});,当f需要类型A,并编译器隐式地产生A对象,或者它从std::initializer_list转换为A

  3. 为什么当g()是模板时,模板类型扣除是否不起作用以给出类型Astd::forward是否有助于将消息从f传送到g,比如说TA类型?

+2

这在C++ 17中有所变化,所以当你说“C++ 11”时,你真的指C++ 11,还是一般意思是“现代C++”? –

+0

对于情况3,这可能起作用:'g(A {t,'@'});'因为正确的类型扣除应该通过临时发生。 – NameRakes

+1

@JerryCoffin注意到[C++ 17的变化被认为是由于缺陷](http://stackoverflow.com/q/31301369/1708801),所以在最近的编译器中,他们将它们应用到C + 11和C++ 14。虽然在这方面有一段时间不一致。 –

回答

3
  1. In 'A a={1,'@'}'' :If {} is deduced as std::initializer_list, then how it's converted from std::initilizer_list to type A?

不,它无关std::initializer_lista只是copy-list-initialized{1,'@'}

  1. In 'f({1,'#'});' When f requires a type A, does compiler implicitly generates an A object, or it converts from std::initializer_list to A?

它仍然与std::initializer_list无关。功能参数是{1,'#'}copy-list-initialized

  1. why when "g()" is a template, the template type deduction doesn't work to give a type A? Does "forward" help to convey the message from f to g, say that T is type A()?

因为这属于non deduced context,模板参数T无法被推断,并导致编译错误。

6) The parameter P, whose A is a braced-init-list, but P is not std::initializer_list or a reference to one:

而且

when does compiler consider {} as std::initializer_list, and when doesn't?

在声明功能可按参数类型为std::initializer_list和你传递一个支撑列表作为参数,然后std::initializer_list将建成。另一种情况是auto,例如

auto x1 = {3}; // x1 is deduced as std::initializer_list<int> 
auto x2{1, 2}; // after C++17, error: not a single element 
       // before C++17, it was std::initializer_list<int> 
auto x3{3}; // after C++17, x3 is deduces as int 
       // before C++17 it was std::initializer_list<int> 

BTW:即使auto它不会{1,'@'}工作,它应该是std::initializer_list<char>,或std::initializer_list<int>

相关问题