为何在MSVC中无法特化返回类型含别名模板的模板?
MSVC模板函数显式特化编译错误分析
问题代码
#include <type_traits> struct G { void operator()() const { } }; template<class T> using MyTrait = std::is_void<T>; struct S { template<class F> std::enable_if_t<MyTrait<decltype(std::declval<F>()())>::value> run(F &&); }; template<> void S::run(G &&);
MSVC编译报错信息
<source>(14): error C2910: 'S::run': cannot be explicitly specialized <source>(16): error C2760: syntax error: 'int' was unexpected here; expected ';'
问题结论
这是MSVC的编译器Bug,而非C++语言规则限制。
具体分析
- 该代码符合C++标准:原函数模板通过
MyTrait(模板别名)结合SFINAE约束限定了重载版本,针对G&&的显式特化是合法的,Clang和GCC的编译行为符合标准要求。 - MSVC的缺陷在于:当SFINAE约束中使用模板别名时,无法正确解析函数模板的显式特化,导致错误判定特化非法;而直接使用
std::is_void时MSVC能正常处理,进一步验证了这是模板别名在SFINAE上下文的处理漏洞。
内容的提问来源于stack exchange,提问作者user541686
相关产品推荐
相关产品推荐

