[temp. deduct.type] p5 告诉我们这是一个非推论上下文:另请参见 [temp.deduct.call] p1 :While reading about a different topic I came across a weird behaviour, at least to me.This whole thought originated from the special interactions between auto and braces. If you write something like:auto A = { 1, 2, 3 }the compiler will deduce A to be a std::initializer_list. The weird thing is that a similar rule applies not only to auto, where there can be special reasons for it, but also to other things.If you write the following:template<typename T>void f(std::vector<T> Vector){ // do something}you can't of course call it in this way:f({ 1, 2, 3});even though a std::vector can be braced initialized. However, if you substitute the std::vector with std::initializer_list, the call works and the compiler will properly deduce int as the type T. The more interesting thing is, however, that in the former case you need to #include <vector>, in the latter you don't need to #include <initializer_list>. This made me think and after a test I realized somehow std::initializer_list don't need its own header, so it is in some way part of the "base" features.Moreover, for everything to make sense, std::initializer_list should be to standard objects in more or less the same way lambdas are to callable objects (in the strictest meaning, that is an object with a operator()). In other words, unnamed braced definitions should default to std::initializer_list just like lambdas are (mostly) unnamed callable objects.Is this reasoning correct? Moreover, can this behaviour be changed and, if so, how?UPDATE: the header for initializer_list was found to be included transitively from iostream (really weird). However, the question remains: why the call works for std::initializer_list and not for std::vector? 解决方案 It is ill-formed (so it requires a diagnostic) to not include the initializer_list header if we use std::initializer_list. We can see this from [dcl.init.list]p2:Mostly likely you are including the header transitively, which is well-formed but makes your code more fragile, so include what you use.We can see from a live godbolt example that having no includes we obtain a diagnostic as required from gcc/clang/MSVC e.g.:error: use of undeclared identifier 'std'void foo( std::initializer_list<int>) { ^and including either <vector> or <iostream> we no longer obtain a diagnostic.Why it does not deduce as you expect is covered by [temp.deduct.type]p5 which tells us this is a non-deduced context:also see [temp.deduct.call]p1: 这篇关于std :: initializer_list,带有括号的初始化和标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-19 11:59