gpt4 book ai didi

c++ - 模板类中的模板成员特化

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:20:26 25 4
gpt4 key购买 nike

#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

  1. 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
}

根据:

  1. 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.

并且因为:

  1. 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com