c++ - 为什么 C++ 在有 ! 时找不到布尔运算符 范围内的运算符?
问题描述
处理一个解析器组合库,这个例子是从这个库派生出来的,尽管很明显一些名字已经被改变以保护无辜者:
#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;
}
}
我有一个模板运算符!仅当 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;
^
解决方案
是的,编译器“放弃”了,因为它认为 ! 运营商是最好的匹配。如果您真的希望编译器忽略该重载,则需要使用一种称为 SFINAE 的技术。
template <typename T,
std::enable_if_t<std::is_same_v<T, std::string>>* = nullptr>
bool operator !(T) {
return true;
}
这样,如果编译器尝试选择此函数,它将无法将参数替换为签名并忽略它。这不会发生在函数体中,这就是您的版本失败的原因。
推荐阅读
- python - 使用单行循环两个字典来创建列表
- unit-testing - 使用和 Mocha 模拟 vuex 动作
- sql-server - How to get records which has more than one entries on another table
- c# - 尝试从 .NET Framework 移植现有的依赖于 powershell 的类库
- android - react-native run-android, Could not resolve all artifacts for configuration ':classpath'
- sql - SQL消除重复,同时合并附加表
- c# - 具有多个条件和 in 子句的 C# EF Linq 语法查询
- c - 新 Linux 内核中的内存隔离,还是什么?
- python - 为什么我在调用 find_cars() 时会出现此错误
- string - SQL Server 2017 - 根据另一个字符串中的列数动态生成一个字符串