首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法使`std::enable_if`为非作用域枚举工作

无法使`std::enable_if`为非作用域枚举工作
EN

Stack Overflow用户
提问于 2020-06-16 17:13:40
回答 1查看 60关注 0票数 0

我正在尝试构建一个实用的ToString函数,它要么调用std::to_string,要么调用定义在其他地方的自定义to_string方法。这就是我为1.0版想出的:

上下文

这里的代码与我正在处理的上下文非常接近。我有来自第三方库的枚举,它们是使用C stlye定义定义的,以及我使用C++样式定义的枚举。

代码语言:javascript
复制
//From my 3rd party library
namespace ThirdPartyNamespace
{
    typedef enum
    {
        UnscopedValue
    } Unscoped;
}

//Defined in Scoped.h
namespace MyNamespace 
{
    enum class Scoped
    {
        ScopedValue
    };

    static std::string to_string(Scoped value)
    {
        return "Enums::Scoped";
    }
}

//Defined in Helpers.h, contains to_string methods for the enums in the 3rd party library
namespace Helpers 
{
    static std::string to_string(ThirdPartyNamespace::Unscoped value)
    {
        return "Enums::Unscoped";
    }    
}

调用代码

代码语言:javascript
复制
ThirdPartyNamespace::Unscoped x = ThirdPartyNamespace::UnscopedValue;
MyNamespace::Scoped y = MyNamespace::Scoped::ScopedValue;

std::cout << Utilities::ToString(x) << std::endl;
std::cout << Utilities::ToString(y) << std::endl;

实用程序

代码语言:javascript
复制
namespace Utilities
{
    template <typename T>
    std::string ToString(const T& value)
    {
        using std::to_string;

        return to_string(value);
    }
}

它为Scoped编译和工作,但为Unscoped写入整数值。我做了一些研究,为了解决这个问题,我需要在枚举类型中使用std::enable_if。在对std::enable_if和SFINAE的工作方式进行了一些研究之后,我想出了我认为能起作用的东西:

实用程序

代码语言:javascript
复制
template<typename T, std::enable_if_t<!std::is_enum<T>::value>* = nullptr>
static std::string ToString(const T& value)
{
    using std::to_string;

    return to_string(value);
}

template<typename T, typename std::enable_if<std::is_enum<T>::value>::type* = nullptr>
static std::string ToString(const T& value)
{
    return to_string(value);
}

但是,这并不是编译。特别是对于Unscoped,它会抛出一个'to_string': identifier not found错误(我用Unscoped注释掉了调用,并按预期进行了编译和工作,从而验证了这是错误)。

我的问题是,为什么编译器找不到我的自定义to_string方法?

一个额外的问题:从我的阅读中,我发现::type* = nullptr“正在为模板'type‘参数设置一个默认值,等于'nullptr'"(来源),这到底意味着什么,为什么要在这里设置一个默认值?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-16 17:31:17

你要么需要

  • 移动 string to_string(第三部分名称空间::未限定的值) 在命名空间ThirdPartyNamespace中找到,这要归功于ADL。
  • 或者,将您的ToString更改为 模板std::string ToString(const & value) {使用std::to_string;使用Helpers::to_string;返回to_string(值);}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62414035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档