SFINAE检查操作员[]比我更困惑
SFINAE check for operator[] is more confused than I am?
我为operator[]
写了一个简单的检查,但是has_subscript_op
结构模板实例化选择了错误的重载:
#include <iostream>
#include <type_traits>
#include <string>
#include <map>
template<class, class, class = void>
struct has_subscript_op : std::false_type
{ };
template<class T, class S>
struct has_subscript_op<T, S, std::void_t<decltype(&std::declval<T>()[S()])>> : std::true_type
{ };
int main()
{
//true, nice
std::cout << "int[][int]: " << has_subscript_op<int[], int>::value << std::endl;
//false, nice
std::cout << "int[][float]: " << has_subscript_op<int[], float>::value << std::endl;
//true, nice
std::cout << "std::string[int]: " << has_subscript_op<std::string, int>::value << std::endl;
//true, WAT?
std::cout << "std::map<std::string, std::string>[int]: " << has_subscript_op<std::map<std::string, std::string>, int>::value << std::endl;
}
使用GCC 6.2.0
Coliru
这是GCC bug,一般bug,还是我在某个地方犯了一个明显的错误?
去掉&
,用declval
作为键:
template<class T, class S>
struct has_subscript_op<T, S, std::void_t<decltype(std::declval<T>()[std::declval<S>()])>> : std::true_type {};
coliru的实例
为什么S()
的检查给出了错误的结果?因为在GCC中,它被认为是0
。std::string
可以用指针构造,而0
恰好是一个空指针常量。
其他编译器不应将S()
视为c++ 14中的0
。
你可以自己试试:
std::map<std::string, std::string> test;
// compile fine, segfault at runtime
auto a = test[0];
// compile error!
auto b = test[2]
检查std::declval
更好,因为它不是0
,也不是2
,而是普通的int
。另外,使用declval
,您的检查将不需要密钥是默认可构造的。
相关文章:
- valgrind-hellgrind与泄漏检查的结果不同
- C++模板来检查友元函数的存在
- 检查输入是否不是整数或数字
- 试图让变量检查数组中的某些内容
- 检查值是否在集合p1和p2中,但不在p3中
- C++概念:如何使用'concept'检查模板化结构的属性?
- 概念TS检查忽略私有访问修饰符
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- 如何在C++中检查2D数组中负值的输入验证
- C++:正在检查LinkedList中的回文-递归方法-错误
- 使用for循环检查数组中的重复项
- 如何检查一个c++字符串中有多少相同的字符/数字
- 检查不带转换的扫描格式
- 如何检查线程是否锁定
- <<操作员在下面的行中工作
- 清除前检查矢量
- 如何处理来自核心指南检查器的关于gsl::at的静态分析警告
- 检查操作员优先级
- SFINAE检查操作员[]比我更困惑