使用限定名称的部分专用化
Partial Specialization using a qualified name
我正在尝试部分专用化元函数的模板并遇到了问题。
我像这样专门化了模板:
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;
它将为您推断出A
,A::Bar
和int
专业化。但请注意,不会尝试检查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>;
};
相关文章:
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- 预处理器:插入结构名称中的前一个行号
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 基类中的函数名称解析
- 调用专用模板时出错"no matching function for call to [...]"
- 模板元程序查找相似的连续类型名称
- 没有名称的C++模板参数
- 模板专用化(按容器):value_type
- 使用限定名称的部分专用化
- 使用另一个模板类的嵌套名称说明符专用化模板类
- C++中名称查找和名称绑定之间的区别
- 类模板方法的专用化,类型名称是类模板 - 错误:参数处的类型/值不匹配
- Clang (C++) 在专用化中找不到名称
- 显式模板专用化和依赖名称查找问题
- C++11中一个专用模板的名称别名
- 具有依赖名称(类型名称)的部分专用化
- 使用Win32 API列出存储在资源专用库(DLL)中的消息id和符号名称
- 在C++中具有名称绑定的EDSL