【问题标题】:C++ Templates Specialization PonderingsC++模板专业化思考
【发布时间】:2015-08-12 09:57:02
【问题描述】:

我遇到了一个应该用模板解决的奇怪情况,但由于某种原因我找不到正确的方法。

对于大多数基本类型(int、bool、char、double、long...)我使用这个函数:

template <typename T>
T foo(T val);

特殊情况是字符串,因为在所有情况下向函数发送参数都是通过发送引用文本(如 “blah”),该文本被推导出为 const char* ,返回值必须是 std::string 像这样:

template ?
std::string foo(const char* val);

所有基本类型的代码都是一样的,但是 string 的情况比较特殊,因为参数和返回值类型不一样,而且字符串的情况需要和基本不同的代码案例。

我尝试了各种奇怪的组合来实现可以编译和工作的代码,但我失败了。 我需要一个比一遍又一遍地编写相同代码更优雅的解决方案。

谢谢!

【问题讨论】:

  • 如果您删除 template ? 部分,它应该可以工作

标签: c++ template-specialization


【解决方案1】:

只需添加一个非模板化的重载:

std::string foo(const char* str)
{
      return foo(std::string{str});
      //or
      // return foo<std::string>(str);
}
std::string foo(char* str); // might need this too

根据你的情况,你可以考虑这个拳头(或代替):

template <std::size_t N>
std::string foo(const char(&str)[N])
{
    return foo(std::string{str});
    //or
    // return foo<std::string>(str);
}

字符串字面量是数组类型,但它们会衰减为指针。例如。 “asd”的类型为const char[4]。所以这更适合字符串文字。

【讨论】:

    【解决方案2】:

    虽然可能首选简单重载 (std::string foo(const char* val);),但您可以使用一种特征作为返回类型:

    template <typename T>
    struct fooRet
    {
        using type = T;
    };
    
    template <>
    struct fooRet<const char*>
    {
        using type = std::string;
    };
    

    然后

    template <typename T>
    typename fooRet<T>::type foo(T val);
    

    可以专门化(如果仍然需要)const char*

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-27
      • 2020-07-18
      • 1970-01-01
      • 1970-01-01
      • 2022-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多