使用模板类型的模板方法的特化

时间:2016-01-08 15:19:01

标签: c++ templates specialization

给出以下代码段:

struct A {
  template <class T >
  void doSomething(T t) {
    std::cout << "doSomething() with " << t << std::endl;
  }
};
template <class T>
struct B {
  T val;
};

如何为模板A::doSomething()专门化B<T>?以下“天真”的尝试不会编译,但可能会解释我想要实现的目标:

template<class T>
void A::doSomething(B<T> t){
  std::cout << "doSomething specialized for B: " << t.val << std::endl;
}

我想实现的目标是什么?如果它是什么语法?

更新

阅读这个帖子,我发现了另一种实现我想要的方法: Specialize a template with a template

由于模板的语法并不总是很容易,这里有一个具有不同专业级别的工作示例:

#include <iostream>
#include <vector>

namespace details {
template<class T> struct Impl;
}
struct A {
  template <class T >
  void doSomething(T t) {
    details::Impl<T>::f(t);
  }
};
template <class T>
struct B {
  T val;
};
namespace details {
template<class T>
struct Impl {
  static void f(T t){std::cout << "default" << std::endl;}
};
template<template<class> class U, class T>
struct Impl<U<T> > {
  static void f(U<T> b){std::cout << "default for U<T>"<< std::endl;}
};
template<>
void Impl<double>::f(double d) {
  std::cerr << "doSomething with double " << d << std::endl;
}
template<class T>
struct Impl<B<T> > {
  static void f(B<T> b);
};
template<class T> 
void Impl<B<T> >::f(B<T> b) {
  std::cerr << "doSomething with B<T> " << b.val << std::endl;
}
template<> 
void Impl<B<int> >::f(B<int> b) {
  std::cerr << "doSomething with B<int> " << b.val << std::endl;
}
}
template<class T>
struct C {
  T toto;
};
int main() {
  A a;
  a.doSomething(12.0);
  B<double> b;
  b.val = 42.0;
  a.doSomething(b);
  B<int> b2;
  b2.val = 42.0;
  a.doSomething(b2);
  C<int> c;
  a.doSomething(c);
  std::vector<int> v;
  a.doSomething(v);
  return 0;
}

1 个答案:

答案 0 :(得分:2)

你不能(部分)专门化它,但你可以重载该功能。喜欢以下(我使这个功能成为一个免费的功能,以便于打字):

#include <iostream>

template<class T> struct B { };

template<class T> void doSomething(B<T> t) {  std::cout << "B\n"; }

template <class T> void doSomething(T t) { std::cout << "T\n"; }

int main() {
    int x;
    B<double> k;

    doSomething(x);
    doSomething(k);
}

输出:

T
B