为什么这个 enable_if 函数模板不能在 VS2017 中特化? [英] Why can't this enable_if function template be specialized in VS2017?

查看:42
本文介绍了为什么这个 enable_if 函数模板不能在 VS2017 中特化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下使用 VS2015 编译,但在 VS2017 中失败并出现以下错误.代码是否在执行 VS2017 中已修复的非标准操作,还是应该由 VS2017 编译?

The following compiled with VS2015, but fails in VS2017 with the below errors. Was the code doing something non standard that has been fixed in VS2017, or should VS2017 compile it?

#include "stdafx.h"
#include <type_traits>

template <typename E>
constexpr auto ToUnderlying(E e)
{
    return static_cast<std::underlying_type_t<E>>(e);
}

template<typename T>
bool constexpr IsFlags(T) { return false; }

template<typename E>
std::enable_if_t<IsFlags(E{}), std::underlying_type_t<E>> operator | (E lhs, E rhs)
{
    return ToUnderlying(lhs) | ToUnderlying(rhs);
}

enum class PlantFlags { green = 1, edible = 2, aromatic = 4, frostTolerant = 8, thirsty = 16, growsInSand = 32 };

bool constexpr IsFlags(PlantFlags) { return true; }

int main()
{
    auto ored = PlantFlags::green | PlantFlags::frostTolerant;

    return 0;
}

错误是:

c:\main.cpp(24): error C2893: Failed to specialize function template 'enable_if<false,_Ty>::type
operator |(E,E)'
        with
        [
            _Ty=underlying_type<_Ty>::type
        ] 
c:\main.cpp(24): note: With the following template arguments:
c:\main.cpp(24): note: 'E=PlantFlags'
c:\main.cpp(24): error C2676: binary '|': 'PlantFlags' does not define this operator or a conversion to a type acceptable to the predefined operator

推荐答案

这绝对是 Visual Studio 中的一个错误.它在 GCC 和 Clang 上编译.它似乎与作为模板参数评估的 constexpr 函数有关.作为临时解决方法,您可以创建模板变量:

This is definitely a bug in Visual Studio. It compiles on GCC and Clang. It seems to be related with constexpr functions evaluated as template parameters. As a temporary workaround, you can make a template variable:

template <typename T>
bool constexpr is_flags_v = IsFlags(T{});

template<typename E>
std::enable_if_t<is_flags_v<E>, std::underlying_type_t<E>> operator | (E lhs, E rhs)
{
    return ToUnderlying(lhs) | ToUnderlying(rhs);
}

关于 Godbolt

这篇关于为什么这个 enable_if 函数模板不能在 VS2017 中特化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆