【发布时间】:2019-08-16 20:19:06
【问题描述】:
#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 编译。那么哪个是对的呢?
但我真正的问题是,假设 clang 是正确的,为什么这又不起作用:
#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>。
【问题讨论】:
-
这些都不应该编译。模板特化只允许在命名空间范围内声明。
-
@Brian 当你说命名空间范围内允许模板特化时,你能详细说明一下吗
-
@Kapil 您希望我详细说明其中的哪一部分?
-
即使我在某个命名空间中添加了这个模板声明,我也会得到同样的错误,所以当你说模板专业化只允许在命名空间范围内是什么意思
-
这段代码在 clang 中运行良好,gcc wandbox.org/permlink/R3dM6pQpsNR5IWje 似乎有问题