作者热门文章
- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
#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>
推导的返回类型在定义之前不能使用。
最佳答案
如果我们看一下 n4810 § 13.8.3
- A member function, a member function template, a member class, a member enumeration, a member class template, a static data member, or a static data member template of a class template may be explicitly specialized for a class specialization that is implicitly instantiated; in this case, the definition of the class template shall precede the explicit specialization for the member of the class template. If such an explicit specialization for the member of a class template names an implicitly-declared special member function (11.3.3), the program is ill-formed.
然而,你可以这样做,两者都是专门的:
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
}
根据:
- In an explicit specialization declaration for a member of a class template or a member template that appears in namespace scope, the member template and some of its enclosing class templates may remain unspecialized, except that the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well.
并且因为:
- A declaration of a function template, class template, or variable template being explicitly specialized shall precede the declaration of the explicit specialization.
因此这不应该在外部模板声明中:
template <typename U>
struct A {
template<typename...Ts> auto func();
template<> auto func<int>() { return std::string{"foo"}; } // should not work
};
我不知道为什么 clang 允许这样做。
但它允许位于声明主模板的命名空间范围内,在本例中为全局命名空间范围。
关于c++ - 模板类中的模板成员特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57530656/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
正如您在 this travis.yml 中看到的那样文件,我的代码依赖于一些第三方库,我在构建项目之前将它们安装在远程系统上。 Travis 每次推送提交时都会下载并构建这些库,这可以避免吗?我的意
我是一名优秀的程序员,十分优秀!