4ZM*_*4ZM 34 c++ templates initializer-list c++11
考虑功能:
template<typename T>
void printme(T&& t) {
for (auto i : t)
std::cout << i;
}
Run Code Online (Sandbox Code Playgroud)
或任何其他期望一个参数具有begin()/ end()启用类型的函数.
以下为什么违法?
printme({'a', 'b', 'c'});
当所有这些都合法时:
printme(std::vector<char>({'a', 'b', 'c'}));
printme(std::string("abc"));
printme(std::array<char, 3> {'a', 'b', 'c'});
Run Code Online (Sandbox Code Playgroud)
我们甚至可以这样写:
const auto il = {'a', 'b', 'c'};
printme(il);
Run Code Online (Sandbox Code Playgroud)
要么
printme<std::initializer_list<char>>({'a', 'b', 'c'});
Run Code Online (Sandbox Code Playgroud)
Lil*_*ard 41
您的第一行printme({'a', 'b', 'c'})是非法的,因为T无法推断出模板参数.如果您明确指定模板参数,它将起作用,例如printme<vector<char>>({'a', 'b', 'c'})或printme<initializer_list<char>>({'a', 'b', 'c'}).
您列出的其他内容是合法的,因为参数具有明确定义的类型,因此T可以推导出模板参数.
您的代码段auto也起作用,因为它il被认为是类型std::initializer_list<char>,因此printme()可以推导出模板参数.
这里唯一"有趣"的部分是auto选择类型,std::initializer_list<char>但模板参数不会.这是因为C++ 11标准的第14.8.2.5/5节明确声明这是模板参数的非推导上下文:
一个函数参数,其关联参数是初始化列表(8.5.4),但该参数没有std :: initializer_list或对可能的cv限定的std :: initializer_list类型的引用.[例:
Run Code Online (Sandbox Code Playgroud)template<class T> void g(T); g({1,2,3}); // error: no argument deduced for T- 结束例子]
然而auto,§7.1.6.4/ 6明确支持std::initializer_list<>
如果初始化程序是braced-init-list(8.5.4),则
std::initializer_list<U>.
Joh*_*hug 10
您还可以重载该函数以显式获取类型为initializer_list的参数.
template<typename T>
void printme(std::initializer_list<T> t) {
for (auto i : t)
std::cout << i;
}
Run Code Online (Sandbox Code Playgroud)
§14.8.2.5/5专门涵盖了这一点
一个函数参数,与其关联的参数是初始化程序列表,但该参数不具有
std::initializer_list或未引用可能由cv限定的std::initializer_list类型。[示例:Run Code Online (Sandbox Code Playgroud)template<class T> void g(T); g({1,2,3}); // error: no argument deduced for T—结束示例]
要使其工作,您可以显式指定模板参数类型。
printme<std::initializer_list<int>>( {1,2,3,4} );
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7447 次 |
| 最近记录: |