模板类中的模板成员专用化
Template member specialization in template class
#include <iostream>
#include <string>
template<typename U>
struct A
{
template<typename... Ts> auto func();
template<> auto func<int>();
};
template<typename U>
template<>
auto
A<U>::func<int>() { return std::string{"foo"}; }
int main()
{
A<float> a{};
std::cout << a.func<int>() << std::endl;
}
这不起作用,因为模板类的模板成员的专用化是不可能的,除非您也专用化该类。 (我读过这个。
但是,如果将成员专用化的定义移动到类定义,它确实有效:
#include <iostream>
#include <string>
template<typename U>
struct A
{
template<typename... Ts> auto func();
template<> auto func<int>() { return std::string{"foo"}; }
};
int main()
{
A<float> a{};
std::cout << a.func<int>() << std::endl;
}
我不确定我是否完全理解为什么。此外,当它使用 clang 时,它不会使用 gcc 编译。那么哪一个是对的呢?
但我真正的问题是,假设叮当做对了,为什么这又不起作用:
#include <iostream>
#include <string>
template<typename U>
struct A
{
template<typename... Ts> auto func();
template<> auto func<U>() { return std::string{"foo"}; }
};
int main()
{
A<int> a{};
std::cout << a.func<int>() << std::endl;
}
这是一个不同的错误,不是非专用模板成员的专用化,而是抱怨在定义之前无法使用具有推导返回类型的func<int>
。
如果我们看n4810 § 13.8.3
一个成员函数,
- 一个成员函数模板,一个成员类,一个 成员枚举、成员类模板、静态数据成员或 类模板的静态数据成员模板可以是显式的 专用于隐式的类专用化 实例;在这种情况下,类模板的定义应 在类成员的显式专用化之前 模板。如果对类的成员进行这种明确的专用化 模板名称隐式声明的特殊成员函数 (11.3.3(,程序格式不正确。
但是,您可以这样做,其中两者都是专门的:
template<typename U>
struct A
{
template<typename... Ts> auto func() { /* ... */ }
};
template <>
template <>
auto A<int>::func<int>()
{
// ok, enclosing class template explicitly specialized
}
虽然这是无效的 c++:
template <typename U>
template <>
auto A<U>::func<int>()
{
// ops: invalid, enclosing class template not explicitly specialized
}
根据:
- 在类成员的显式专用化声明中 模板或命名空间范围中显示的成员模板, 成员模板及其某些封闭类模板可能会保留 非专业,但声明不得明确 专用化类成员模板(如果其封闭类模板( 也没有明确的专业化。
并且因为:
- 函数模板、类模板或变量的声明 明确专门的模板应在声明之前 明确的专业化。
因此,这不应该在外部模板声明中:
template <typename U>
struct A {
template<typename...Ts> auto func();
template<> auto func<int>() { return std::string{"foo"}; } // should not work
};
我不知道为什么叮当允许这样做。
但它允许位于声明主模板的命名空间作用域中,在本例中为全局命名空间作用域。
相关文章:
- 静态数据成员模板专用化的实例化点在哪里
- 成员变量如何使用专用类模板?
- GCC 7 中模板类的模板成员函数的专用化
- C++ 类模板部分专用化,而不专用化所有成员函数
- 专用于可变参数模板成员函数
- 对专用模板成员的未定义引用
- 对类模板成员的显式专用化的约束
- 具有专用成员函数的默认模板参数
- 如何正确地显式实例化具有完全专用成员的模板类
- C++模板类中的非专用成员
- 运算符<<重载时无法访问专用成员(指定指针)
- 避免强制转换以访问派生类的专用成员
- 枚举类型参数的专用成员模板
- 组织专用成员 Vector<Vector 接口的最佳方式<Type>>
- 基于基类的专用成员函数
- C++模板:专用成员函数,用于解决主模板中不明确的重载情况
- 导出/定义静态模板专用成员变量C++
- 无法访问QXmlStreamReader的专用成员(运算符=)
- 类专用成员-数组访问失败
- C++中非模板类的专用成员函数