使用限定名称的部分专用化

Partial Specialization using a qualified name

本文关键字:专用 定名称      更新时间:2023-10-16

我正在尝试部分专用化元函数的模板并遇到了问题。

我像这样专门化了模板:

template <typename A, typename B>
struct Foo;
template <typename A, typename B1>
struct Foo<A, typename A::template Bar<B1>> {
/* use both A and B1*/
};
template <typename A, typename B1>
struct Foo<A, typename A::template Xyz<B1>> {
/* use both A and B1*/
};

但是,这会导致(Visual Studio 2019(在

Error C2764: 'B1': template parameter not used or deducible in partial specialization 'Foo<A,A::Bar<B1>>' (5, 47)

我认为这是因为我在专业化(typename A::template Bar<B1>(中使用了模板参数A作为限定符。

有没有办法规避这一点并使用模板专用化中的参数作为限定符?

注意:在我的用例中,第一个参数从来没有真正专门化过。 从理论上讲,它可以将专用模板嵌套在另一个模板类中(即柯里化元函数(,但模板只能在命名空间范围内专用。

使用模板模板参数可以解决:

template <typename A, typename B>
struct Foo;
template <typename TA, template<class> class TBar,  typename B1>
struct Foo<TA, TBar<B1>> {};

鉴于

struct A
{
template<class T>
struct Bar {};
};

你可以形成

Foo<A, A::Bar<int>> x;

它将为您推断出AA::Barint专业化。但请注意,不会尝试检查A::Bar中的A是否与作为第一个模板参数给出的A匹配;目前还不清楚你期望会发生什么,比如说,一个Foo<double, A::Bar<int>>

https://godbolt.org/z/hGhsZm

我认为这是因为我在专用化中使用了模板参数 A 作为限定符(类型名称 A::template Bar(。

我不这么认为。

假设A

如下所示
struct A
{ 
template <typename B>
using Bar = int; 
};

并且您定义了一个Foo<A,A::Bar<B1>>.

A::Bar<B1>int

所以你正在定义Foo<A, int>.

编译器如何从int推断出B1

在我看来,它不能。

可能的解决方案(取决于您的需求(:如果您需要通过B1进行专用化,但您需要在Foo内部使用A::Bar<B1>,您可以使用B1本身作为第二个参数,A::Bar<B1>作为在Foo中使用类型

template <typename A, typename B1>
struct Foo<A, B1> {
using bType = A::template Bar<B1>;
};