c++ - 为什么 Visual Studio 不允许我在 enable_if 中使用模板化的 constexpr 函数?

标签 c++ c++11 templates visual-studio-2015 constexpr

所以我将其归结为最小的、完整的、可验证的示例,而且 Visual Studio 2015 似乎不允许我使用模板化的 constexprenable_if 中运行.

例如:

template <typename T>
constexpr bool condition() { return sizeof(T) > 1; }

给我错误:

error C2995: enable_if<_Test,T>::type test(void): function template has already been defined

当我尝试在替换中使用它时,失败不是这样的错误编译:

template <typename T>
enable_if_t<condition<T>()> test() { cout << "true\n"; }

template <typename T>
enable_if_t<!condition<T>()> test() { cout << "false\n"; }

这在 gcc 中工作正常:http://ideone.com/m9LDdS
如果我删除 condition 的模板化,它在 Visual Studio 2015 中工作正常.我相信constexpr 中引入了功能,为什么 Visual Studio 2015 不支持这个?这是一个错误吗?

最佳答案

问题似乎是 MSVC14/VS2015 无法结合 constexpr 函数的返回值作为模板参数正确解析 SFINAE 表达式。

作为解决方法,您可以将 constexpr 的返回值分配给结构的“静态常量”成员,并将该成员用作模板参数。

#include <type_traits>
#include <iostream>

using std::enable_if_t;
using std::cout;

template <typename T>
constexpr bool condition() { return sizeof(T) > 1; }

template <typename T>
struct condition_ { static const bool value = condition<T>();};

template <typename T>
enable_if_t<condition_<T>::value> test() { cout << "true\n"; }
template <typename T>
enable_if_t<!condition_<T>::value> test() { cout << "false\n"; }

int main() {
    test<int>();
    test<bool>();
    return 0;
}

http://rextester.com/VVNHB62598


您还在评论中提到您的实际问题出现在与您的 MCVE ( How can I Initialize a div_t Object? ) 不同的情况下

对于这种情况,解决方法可能如下所示:

#include <type_traits>
#include <cstdlib>
#include <utility>


template <typename T>
using divtype = decltype(std::div(std::declval<T>(), std::declval<T>()));


template <typename T>
struct condition
{
    static const bool value = divtype<T>{ 1, 0 }.quot != 0;
};


template <typename T>
std::enable_if_t<condition<T>::value, divtype<T>> make_div(const T quot, const T rem) { return{ quot, rem }; }

template <typename T>
std::enable_if_t<!condition<T>::value, divtype<T>> make_div(const T quot, const T rem) { return{ rem, quot }; }

int main() {

    make_div<int>(1, 2);
    return 0;
}

http://rextester.com/ULDFM22040


根据这个Visual Studio C++ Team blog entry VS2015 没有(完全)支持 Expression SFINAE还没有。

[1] We’re planning to start implementing Expression SFINAE in the compiler immediately after 2015 RTM, and we’re planning to deliver it in an Update to 2015, supported for production use. (But not necessarily 2015 Update 1. It might take longer.)

关于c++ - 为什么 Visual Studio 不允许我在 enable_if 中使用模板化的 constexpr 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41593649/

相关文章:

c++ - 为什么在 C++ 中在变量后附加 <eax>

c++ - 如果包为空,是否对可变参数包类型执行替换?

c++ - 带有显式右值转换运算符的 static_cast

c++ - Boost.python 继承自包装类

c++ - C++ lambda 构造函数参数可以捕获构造变量吗?

c++ - 对数组使用unique_ptr,如何在 Debug模式下查看每个值 "local"或 "watch"标签

c++ - 派生类作为默认参数 g++

c++ - 将 std::vector 作为模板模板参数传递时出错 - 在 GCC 中有效,在 MSVC 中失败

c++ - 自动将类成员注册到 C++ 中的包含对象

c++ - 为具有不同签名的函数的派生类设计基类