我正在尝试构建一个实用的ToString函数,它要么调用std::to_string,要么调用定义在其他地方的自定义to_string方法。这就是我为1.0版想出的:
上下文
这里的代码与我正在处理的上下文非常接近。我有来自第三方库的枚举,它们是使用C stlye定义定义的,以及我使用C++样式定义的枚举。
//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";
}
}调用代码
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;实用程序
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的工作方式进行了一些研究之后,我想出了我认为能起作用的东西:
实用程序
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'"(来源),这到底意味着什么,为什么要在这里设置一个默认值?
发布于 2020-06-16 17:31:17
你要么需要
ThirdPartyNamespace中找到,这要归功于ADL。ToString更改为
模板std::string ToString(const & value) {使用std::to_string;使用Helpers::to_string;返回to_string(值);}https://stackoverflow.com/questions/62414035
复制相似问题