问题描述
我有一个类 A
,它是一个模板,如果该类是具有 foo()
泛型的 std::vector<T>
,我想专门化方法 T
,我得到错误:无效使用不完整的类型。我想避免为所有可能的向量编写所有特化。
#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;
}
解决方法
如果 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>{}); }
};
,
仅使用 c++20 contrians:
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