【问题标题】:Generic function template deduction over existing function overloads对现有函数重载的通用函数模板推导
【发布时间】: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。)。

但是,这种方法的问题在于,即使&lt;string&gt; 已经为其提供了重载的类型,也会推导出重载模板。

我的问题是是否有办法强制仅在没有可用的非模板定义时才使用非模板重载?

  • 正交,但在这种情况下使用static_assert(),而不是throw,并且不要专门化std,这是许多问题的根源。
  • 要回答这个问题 - 添加更多带有默认值的参数
  • 如果这样做,错误将在运行时发生,即运行时异常。只需...不做任何这些,现在将在编译时报告错误,而不是运行时。这是一个更好的地方。
  • @joaocandre 基本上扩展 std 是 UB,但有一些例外:en.cppreference.com/w/cpp/language/extending_std
  • 此外,还有一个解决方法:namespace joaotl { using namespace std; /* your codes */ }。然后你可以为to_stringjoaotl而不是std,它会推断出标准或你的标准,但你不需要扩展std。但是,您仍然需要“添加参数”技巧。

标签: c++ templates sfinae


【解决方案1】:

我最终在不同的命名空间上声明了to_string,并利用类型特征将基本类型委托给 STL 的std::to_string

namespace extra {

template < typename T >
struct invalid : std::false_type { /* ... */ };

template < typename oT, typename iT >
inline oT to_string(const iT& in) {
    // static_assert(invalid< iT >::value, "Invalid call to extra::to_string(): missing template specialization for required type!");   // never compiles
    throw std::runtime_error("Invalid call to extra::_to_string(): missing template specialization for required types[" + std::string(typeid(T).name()) + "]!");
}

}  // namespace extra


template < typename T >
void func(const T& arg) {
    // ...
    if constexpr (std::is_arithmetic< T >()) {
        std::cout << std::to_string(arg);
    } else {
        std::cout << extra::to_string(arg);
    }
    // ...
}

尽管我仍在试图弄清楚如何正确编写静态断言以在编译期间生成错误,但在这个阶段,这符合我的需要。

【讨论】:

    猜你喜欢
    • 2012-12-03
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    • 2018-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多