C++ 模板参数推断失败时decltype成功?
我想知道,当带bbb的行没有注释掉,但前面的行没有注释掉时,为什么下面的代码会按预期编译和工作,但当带aaa标记的行没有注释掉,而带bbb的行被注释掉时,代码会失败:C++ 模板参数推断失败时decltype成功?,c++,templates,c++11,decltype,template-argument-deduction,C++,Templates,C++11,Decltype,Template Argument Deduction,我想知道,当带bbb的行没有注释掉,但前面的行没有注释掉时,为什么下面的代码会按预期编译和工作,但当带aaa标记的行没有注释掉,而带bbb的行被注释掉时,代码会失败: #include <iostream> #include <string> using String = std::string; struct Person { String m_name; explicit Person(String const &name): m_name(n
#include <iostream>
#include <string>
using String = std::string;
struct Person {
String m_name;
explicit Person(String const &name): m_name(name) {}
operator String() const { return "\"" + m_name + "\""; }
};
template<class T> bool isEqual(
T const& a,
//T const& // does NOT compile // aaa
decltype(a) // DOES compile // bbb
b){ return a == b; }
int main()
{
String const plain("plain");
Person const jb("James");
bool b = isEqual(plain, jb);
std::cout << "isEqual(plain, person) is " << ( b ? "true" : "false" ) << "\n";
}
#包括
#包括
使用String=std::String;
结构人{
字符串m_name;
显式Person(stringconst&name):m_name(name){}
运算符字符串()常量{return“\”+m\u name+“\”;}
};
模板布尔相等(
康斯特公司,
//T const&//不编译//aaa
decltype(a)//编译//bbb
b) {返回a==b;}
int main()
{
字符串常量普通(“普通”);
康斯特律师事务所(“詹姆斯”);
bool b=等质量(普通,jb);
std::cout当您执行以下操作时:
template<class T>
bool isEqual(T const& a, T const& b)
template<class T>
bool isEqual(T const& a, decltype(a) b)
只需要推导一个参数/参数对。T
将被推导为String
,并且由于Person
可以转换为String
(通过转换函数操作符String()
),因此此操作非常有效
这类似于identity
技巧,我们只需强制一个参数位于非推断上下文中:
template <typename T>
struct identity { using type = T; };
template <typename T>
bool isEqual(T const& a, typename identity<T>::type const& b);
模板
结构标识{using type=T;};
模板
bool-isEqual(T const&a,typename-identity::type const&b);
这里再次说明,只有一对进行了类型推断,T
被推断为String
,因此b
的类型也是String const&
,但不是因为它是这样推断的,而是因为它在中被替换了