gct*_*gct 1 c++ templates c++11
在解析器组合库上工作,这个例子来源于此,但显然有些名称已被更改以保护无辜者:
#include <string>
#include <stdio.h>
using namespace std;
template <typename T> struct only_string;
template <> struct only_string<string> {};
struct another_type {
explicit operator bool() const { return true; }
};
// only substitute if T is string
template <typename T>
bool operator !(T) {
only_string<T> a;
return true;
}
int main() {
another_type a;
if (!a) {
return 1;
} else {
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个模板操作员!应该只在T是字符串时替换,而另一种类型在其上有bool操作符.如果我试着打电话给a,它首先找到操作员,无法替换并放弃.谁能解释这种行为以及如何纠正它?
这是g ++ 5.4.0的输出
> g++ -std=c++11 test.cc -o test
test.cc: In instantiation of ‘bool operator!(T) [with T = another_type]’:
test.cc:24:10: required from here
test.cc:17:20: error: ‘only_string<another_type> a’ has incomplete type
only_string<T> a;
^
Run Code Online (Sandbox Code Playgroud)
是的编译器"放弃了",因为它认为!运营商是最佳匹配.如果您真的希望编译器忽略该重载,则需要使用一种名为SFINAE的技术.
template <typename T,
std::enable_if_t<std::is_same_v<T, std::string>>* = nullptr>
bool operator !(T) {
return true;
}
Run Code Online (Sandbox Code Playgroud)
这样,如果编译器尝试选择此函数,它将无法将参数替换为签名并将忽略它.这不会发生在函数体中,这就是您的版本失败的原因.