【发布时间】:2017-09-12 16:04:21
【问题描述】:
我有一个快速示例:
#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;
}
Clang 会报这个错误:
testArray.cpp:16:5: 错误: 没有匹配函数调用'g' g({1,'@'});//修正:g({1,'@'}) ^ testArray.cpp:9:6:注意:候选模板被忽略:无法推断 模板参数“T” 无效 g(T&& t) ^我的问题是:
在
A a={1,'@'};中,如果{}推导出为std::initializer_list,那么如何将std::initilizer_list转换为类型A?-
在
f({1,'#'});中,当f需要A类型时,编译器是隐式生成A对象,还是从std::initializer_list转换为A? 为什么,当
g()是一个模板时,模板类型推导不起作用给一个类型A?std::forward是否有助于将消息从f传达给g,说T是类型A?
【问题讨论】:
-
这在 C++17 中有所改变,所以当你说“C++11”时,你真的是指 C++11,还是泛指“现代 C++”?跨度>
-
对于情况 3,这可能有效:
g(A{t,'@'});因为适当的类型推导应该通过临时发生。 -
@JerryCoffin 请注意 the C++17 changes were considered due to a defect 等在最近的编译器中,他们将它们应用回 C+11 和 C++14。虽然这方面有一段时间不一致。
标签: c++ c++11 templates types initializer-list