【发布时间】:2022-08-19 06:50:11
【问题描述】:
我正在编写一个可扩展的库,可以方便地为自定义类型重载 STL 的 to_string()。为此,我设计了一个通用的重载模板,如果没有专门化就会抛出异常:
namespace std {
// ...
template < typename T >
inline std::string to_string(const T& in, const std::string& separator = \",\") {
throw std::runtime_error(\"invalid call to \" + std::string(__func__) + \"(): missing template specialization for type \" + typeid(T).name());
}
} // namespace std
这很有用,主要是因为描述将提供关于该问题以及如何解决它的清晰解释,并避免必须使用多态性来实现派生实现(该函数仅在某些应用程序(如序列化、I/O)中很少/可选地需要, ETC。)。
但是,这种方法的问题在于,即使<string> 已经为其提供了重载的类型,也会推导出重载模板。
我的问题是是否有办法强制仅在没有可用的非模板定义时才使用非模板重载?
-
正交,但在这种情况下使用
static_assert(),而不是throw,并且不要专门化std,这是许多问题的根源。 -
要回答这个问题 - 添加更多带有默认值的参数
-
如果这样做,错误将在运行时发生,即运行时异常。只需...不做任何这些,现在将在编译时报告错误,而不是运行时。这是一个更好的地方。
-
@joaocandre 基本上扩展
std是 UB,但有一些例外:en.cppreference.com/w/cpp/language/extending_std -
此外,还有一个解决方法:
namespace joaotl { using namespace std; /* your codes */ }。然后你可以为to_string写joaotl而不是std,它会推断出标准或你的标准,但你不需要扩展std。但是,您仍然需要“添加参数”技巧。