【问题标题】:Is it possible to specialize a method of a template class on another templated class?是否可以在另一个模板类上专门化模板类的方法?
【发布时间】:2021-01-28 21:25:43
【问题描述】:

我有一个类A,它是一个模板,如果该类是std::vector<T>T 泛型,我想专门化方法foo(),我收到错误:无效使用不完整类型.我想避免为所有可能的向量编写所有特化。

#include <iostream>
#include <vector>

template<typename V>
struct A {
  void foo() {
    std::cout << "A<V>\n";
  }
};

template<typename T>
void A<std::vector<T>>::foo() {
  std::cout << "A<V<T>>\n";
}

int main() {
  C<int> a;
  C<std::vector<int>> b;

  return 0;
}

【问题讨论】:

  • 您可以将整个类专门化为向量,或者使用 SFINAE 专门化函数本身

标签: c++ templates c++20 template-specialization template-templates


【解决方案1】:

如果foo() 不依赖于A 的其他元素,则可以通过基类继承它并专门化基类。

我的意思如下

template <typename>
struct Base
 { void foo() { std::cout << "A<V>\n"; } };

template <typename ... Ts>
struct Base<std::vector<Ts...>>
 { void foo() { std::cout << "A<V<Ts...>>\n"; } };

template <typename T>
struct A : public Base<T>
 { };

另一种可能的解决方案是标签调度:根据需要开发两个foo() 函数并“启用”正确的函数。

例如

template <typename>
struct is_vector : public std::false_type
 { };

template <typename ... Ts>
struct is_vector<std::vector<Ts...>> : public std::true_type
 { };

template <typename T>
struct A
 {
   void foo (std::true_type) { std::cout << "A<V<Ts...>>\n"; }

   void foo (std::false_type) { std::cout << "A<V>\n"; }

   void foo () { foo(is_vector<T>{}); } 
 };

【讨论】:

  • 有了is_vector trait,if constexpr (C++17) 可以用来代替(旧的)标签调度。
  • @Jarod42 - 我想,在这种特殊情况下,还有一个简单的if。但问题是关于专门化一种方法。
【解决方案2】:

仅使用 c++20 控件:

template <typename V>
struct A {
  void foo() { std::cout << "A<V>\n"; }

  void foo() requires (std::same_as<V, std::vector<typename V::value_type>>) {
    std::cout << "A<V<T>>\n";
  }
};

然后这个工作:

A<int>{}.foo(); // call normal one
A<std::vector<int>>{}.foo(); // call specialized one

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 1970-01-01
    • 2013-04-09
    • 2016-10-12
    • 1970-01-01
    • 1970-01-01
    • 2014-02-06
    相关资源
    最近更新 更多