所以我把它归结为最小的,完整的,可验证的例子,看起来Visual Studio 2015似乎不允许我使用一个模板化的constexpr
函数enable_if
.
例如:
templateconstexpr bool condition() { return sizeof(T) > 1; }
给我错误:
错误C2995 ::
enable_if<_Test,T>::type test(void)
功能模板已经定义
当我尝试在替换中使用它时,失败不是像这样的错误编译:
templateenable_if_t ()> test() { cout << "true\n"; } template enable_if_t()> test() { cout << "false\n"; }
这在gcc中运行良好:http
://ideone.com/m9LDdS
如果我删除了它的模板化,它在Visual Studio 2015中工作正常condition
.我相信constexpr
函数是在c ++ 11中引入的,为什么Visual Studio 2015不支持这个?这是一个错误吗?
问题似乎是MSVC14/VS2015无法正确解析SFINAE表达式并结合constexpr函数的返回值作为模板参数.
作为一种变通方法,您可以将constexpr的返回值赋给结构的"static const"成员,并将此成员用作模板参数.
#include#include using std::enable_if_t; using std::cout; template constexpr bool condition() { return sizeof(T) > 1; } template struct condition_ { static const bool value = condition ();}; template enable_if_t ::value> test() { cout << "true\n"; } template enable_if_t::value> test() { cout << "false\n"; } int main() { test (); test (); return 0; }
http://rextester.com/VVNHB62598
您还在评论中提到您的实际问题出现在另一个案例中而不是您的MCVE(如何初始化div_t对象?)
对于这种情况,解决方法可能如下所示:
#include#include #include template using divtype = decltype(std::div(std::declval (), std::declval ())); template struct condition { static const bool value = divtype { 1, 0 }.quot != 0; }; template std::enable_if_t ::value, divtype > make_div(const T quot, const T rem) { return{ quot, rem }; } template std::enable_if_t::value, divtype > make_div(const T quot, const T rem) { return{ rem, quot }; } int main() { make_div (1, 2); return 0; }
http://rextester.com/ULDFM22040
根据Visual Studio C++团队的博客文章 VS2015还没有(完全)支持Expression SFINAE.
[1]我们计划在2015 RTM之后立即开始在编译器中实现Expression SFINAE,并且我们计划在2015年更新中提供它,支持生产使用.(但不一定是2015年更新1.可能需要更长时间.)