如何解决不能使用SFINAE,在MSVC10中键入traits和static_assert
| 我一直在研究使用一些明智的静态断言来改善错误消息。这是一个例子:#include <type_traits>
template<typename T> struct is_less_than_comparable {
template<typename Test> static char test(decltype(*static_cast<Test*>(nullptr) < *static_cast<Test*>(nullptr)));
template<typename Test> static int test(...);
static const bool value = std::is_same<char,decltype(test<T>(true))>::value;
};
template<typename K,typename V> class map {
public:
static_assert(is_less_than_comparable<K>::value,\"Key type must be less-than comparable!\");
};
struct x {};
int main() {
map<x,int> intmap;
}
IDEONE会很高兴地用我希望得到的漂亮清晰的错误消息拒绝此代码(无论如何,一旦将nullptr替换为0)。但是,即使我添加了一些成员函数并开始对其进行调用,MSVC也不会触发静态断言并可以很好地编译此代码。
解决方法
问题在于使用VC ++ 2010处理元函数
is_less_than_comparable
,而不是not2ѭ。
如果将代码更改为:
static const bool value = std::is_same<double,decltype(test<T>(true))>::value;
然后,无论选择哪个过载,它都是错误的。然后断言触发。
显然选择了错误的重载,SFINAE不会删除具有“ 4”返回类型的候选对象。
更简单的测试(错误打印1
):
#include <type_traits>
template<typename T> struct is_less_than_comparable {
template<typename Test> static char test(decltype(*static_cast<Test*>(nullptr) < *static_cast<Test*>(nullptr)) b);
template<typename Test> static int test(...);
static const bool value = std::is_same<char,decltype(test<T>(true))>::value;
};
struct x {};
#include <iostream>
int main() {
std::cout << is_less_than_comparable<x>::value << std::endl;
}
出于显而易见的原因,编译器提供了一个“ 7”运算符,从而生成了“ 8”。如果提供了用户定义的比较运算符,则正确选择其返回类型。此运算符不带标题之一,我可以将re9解析为bool
,不包含标题。
这会产生适当的错误:
decltype(*(x*)nullptr < *(x*)nullptr) b;
error C2676: binary \'<\' : \'x\' does not define this operator or a conversion to a type acceptable to the predefined operator
我认为这与VC ++不执行模板相关参数的两阶段查找有关。
, 我不确定您在这里的答案中正在寻找什么,因此这是在VC ++ 2010中可以正常工作的类型特征:
#include <type_traits>
namespace supports
{
namespace details
{
struct return_t { };
template<typename T>
static T& make();
}
template<typename T>
details::return_t operator <(T const&,T const&);
template<typename T>
struct less_than : std::integral_constant<
bool,!std::is_same<
decltype(details::make<T>() < details::make<T>()),details::return_t
>::value
> { };
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。