C++ 无例外+;无法在MSVC下编译declval
我试图实现我对我的SO问题的答案: 我的目标是检测模板类C++ 无例外+;无法在MSVC下编译declval,c++,templates,visual-c++,compiler-errors,sfinae,C++,Templates,Visual C++,Compiler Errors,Sfinae,我试图实现我对我的SO问题的答案: 我的目标是检测模板类T中是否存在void cancel()noexcept方法。 以下是我的最简单的例子: #include <iostream> #include <type_traits> template<class T, class = void> struct has_cancel : std::false_type {}; template<class T> struct has_cancel&l
T
中是否存在void cancel()noexcept
方法。
以下是我的最简单的例子:
#include <iostream>
#include <type_traits>
template<class T, class = void>
struct has_cancel : std::false_type {};
template<class T>
struct has_cancel<T,
typename std::void_t<decltype(std::declval<T>().cancel()),
typename std::enable_if_t<noexcept(std::declval<T>().cancel())>
>
> : std::true_type {};
void print_has_cancel(std::true_type) {
std::cout << "cancel found" << std::endl;
}
void print_has_cancel(std::false_type) {
std::cout << "cancel not found" << std::endl;
}
struct A{
};
struct B {
void cancel(){}
};
struct C {
int cancel() noexcept {}
};
struct D{
void cancel() noexcept {}
};
int main(){
print_has_cancel(has_cancel<A>());
print_has_cancel(has_cancel<B>());
print_has_cancel(has_cancel<C>());
print_has_cancel(has_cancel<D>());
return 0;
}
#包括
#包括
模板
结构有_cancel:std::false_type{};
模板
结构有_cancel:std::true_type{};
作废打印已取消(标准::真打印类型){
std::cout C:\Users\David Haim\source\repos\cpp_sandbox\cpp_sandbox\cpp_sandbox.cpp(10,1):消息:类型为“\u添加\引用::\右值”
1> C:\Users\David Haim\source\repos\cpp_sandbox\cpp_sandbox\cpp_sandbox.cpp(10,19):错误C2056:非法表达式
1> 已完成构建项目“cpp_sandbox.vcxproj”--失败。
======生成:0成功,1失败,0最新,0跳过==========
经过一些研究,问题在于语法noexcept(std::declval().something())
-MSVC拒绝理解这一行
1) MSVC为什么抱怨?是在代码中还是在编译器中
2) 我怎样才能让它继续编译呢?MSVC的语法本身没有问题。它似乎只是假设SFINAE在这种情况下不适用,所以将
void
替换为type会产生错误。为什么或者标准中是否支持这一点,我现在不知道(但我对此表示怀疑)
通过将声明中的noexcept
条件移动到struct
的定义中,可以很容易地解决这个问题,这样,如果第一个decltype
格式错误(即如果.cancel()
根本不存在)并且SFINAE启动,它就永远不会被替换:
template<class T>
struct has_cancel<T,
typename std::void_t<decltype(std::declval<T>().cancel()) >
> : std::bool_constant<noexcept(std::declval<T>().cancel())> {};
模板
结构有_cancel:std::bool_常量{};
我相信一些东西,但还没有在VS中实现。然而,旧的SIFANE技巧可能会有所帮助?请看@P0W,它不会检测取消
是否不例外。我对任何版本的标准都很满意,只要这个技巧也能检测到不例外。我查了一下,发现这个:“直到CWG 1558(一个C++14缺陷),别名模板中未使用的参数不能保证确保SFINAE,可以忽略。@Frodyne这似乎不是MSVC所考虑的。即使删除了void\t
,并且仅使用了一个简单的enable\u if\t
,它仍然会产生相同的错误:
template<class T>
struct has_cancel<T,
typename std::void_t<decltype(std::declval<T>().cancel()) >
> : std::bool_constant<noexcept(std::declval<T>().cancel())> {};