【问题标题】:Specialize template of templated data type特化模板化数据类型的模板
【发布时间】:2019-05-20 13:33:16
【问题描述】:

我有这种情况:

#include <vector>

template<typename T>
T f() { return T(); }

template<>
template<typename T>
std::vector<T> f<std::vector<T>>() {
    return { T() };
}

int main(){
    f<std::vector<int>>();
}

我正在尝试为 std::vector&lt;T&gt; 专门化模板,但出现此错误:

error: too many template-parameter-lists

std::vector<T> f<std::vector<T>>() {

我怎样才能专攻std::vector&lt;T&gt;

【问题讨论】:

  • 不允许对模板函数进行部分特化。
  • 这种情况我更喜欢标签调度:template&lt;&gt;struct Tag{}; template&lt;typename T&gt; T f(tag&lt;T&gt;) {/*..*/} template&lt;typename T&gt; std::vector&lt;T&gt; f(tag&lt;std::vector&lt;T&gt;&gt;) {/*..*/}

标签: c++ templates template-specialization


【解决方案1】:

没有部分专用的函数模板。您正在做的是创建一个新模板,因此正确的语法是:

template<typename T>
std::vector<T> f() {
    return { T() };
}

这会重载函数名f,并且两个模板是独立的。但是,通过这两种重载,几乎所有对 f 的调用都会模棱两可,包括您的 main() 中的一个示例。

编辑:

如果您删除了对于类部分专业化也无效的 template&lt;&gt; 行,那么 clang 会生成更多有用的错误消息:

错误:不允许非类、非变量偏特化f&lt;std::vector&lt;T,std::allocator&lt;_Tp1&gt; &gt; &gt;

std::vector<T> f<std::vector<T>>() {

【讨论】:

    【解决方案2】:

    如果一个问题是 X,一个解决方案是 Y,那么函数模板的特化通常是 Z。那是无论如何都可以特化的时候。您不能部分特化函数模板,只能重载它们。

    这里的解决方案是使用助手。一个您可以专门化的类模板,它将完成这项工作。同时函数模板只转发给它。

    namespace detail {
        template<typename T>
        struct f {
            static T work() { return T(); }
        };
    
        template<typename T>
        struct f<std::vector<T>> {
            static std::vector<T> work() { return {T()}; }
        };
    }
    
    template<typename T>
    T f() { return detail::f<T>::work(); }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多