为什么允许使用功能模板的私有类型的明确专业化?

发布于 2025-01-29 04:18:56 字数 1368 浏览 3 评论 0原文

https://godbolt.org/z/s5yh8e6b8

具有私有类型的明确专业允许类模板,但对于功能模板而言不允许使用?

假设我们有一个类:

class pepe
{
    struct lolo
    {
        std::string name = "lolo";
    };
public:
    static lolo get()
    {
        return {};
    }
};
  • 可以明确专业化的类模板。
  • 在隐式实例化时,功能模板没有问题。
  • 尽管您无法创建spec_class< pepe :: lolo> {},因为pepe :: lolo是不可能的。
template <typename>
struct spec_class
{};

// this is ok
template <>
struct spec_class<pepe::lolo>
{};

// this will be ok also upon implicit instantiation
template <typename T>
void template_func(const T &t)
{
    std::cout << "implicit: " << t.name << std::endl;
}

但是:

// this is not ok!
// template <>
// void template_func(const pepe::lolo &p)
// {
//     std::cout << "explicit: " << p.name << std::endl;
// }

// this is ok, but more or less understandable why
template <>
void template_func(const decltype(pepe::get()) &p)
{
    std::cout << "explicit: " << p.name << std::endl;
}

// not ok, but expected
// void func(const pepe::lolo&)
// {}

所以: 为什么禁止对功能模板进行显式专业?

https://godbolt.org/z/s5Yh8e6b8

I don't understand the reasoning behind this: why is explicit specialization with private type allowed for class templates but not for function templates?

Say we have a class:

class pepe
{
    struct lolo
    {
        std::string name = "lolo";
    };
public:
    static lolo get()
    {
        return {};
    }
};
  • Class template can be explicitly specialized.
  • And function templates have no problems upon implicit instantiation.
  • Though you can't create spec_class<pepe::lolo>{} because pepe::lolo is inaccessable.
template <typename>
struct spec_class
{};

// this is ok
template <>
struct spec_class<pepe::lolo>
{};

// this will be ok also upon implicit instantiation
template <typename T>
void template_func(const T &t)
{
    std::cout << "implicit: " << t.name << std::endl;
}

But:

// this is not ok!
// template <>
// void template_func(const pepe::lolo &p)
// {
//     std::cout << "explicit: " << p.name << std::endl;
// }

// this is ok, but more or less understandable why
template <>
void template_func(const decltype(pepe::get()) &p)
{
    std::cout << "explicit: " << p.name << std::endl;
}

// not ok, but expected
// void func(const pepe::lolo&)
// {}

So:
Why is explicit specialization prohibited for a function template?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

萌梦深 2025-02-05 04:18:56

从C ++ 20中,在功能模板专业化的参数中使用私有成员是完全有效的,因为 pr0692 。特别是,以下措辞添加到 temp.spec.general#6 :

通常的访问检查规则不适用于声明明确的实例化或明确专业化的名称,但在功能主体中出现的名称除外,默认参数, base-子句成员规范 enumerator-list 或静态数据成员或变量模板初始化器。

[注1:特别是,函数声明器中使用的模板参数和名称(包括参数类型,返回类型和异常规格)可以是私有类型或通常无法访问的对象。 - end Note ]

(强调矿山)

不编译的代码是由a GCC错误97942 ,它在clang中的编译很好。 demo

From C++20, using private members in the parameter of a specialization of a function template is perfectly valid, due to PR0692. In particular, the following wording was added to temp.spec.general#6:

The usual access checking rules do not apply to names in a declaration of an explicit instantiation or explicit specialization, with the exception of names appearing in a function body, default argument, base-clause, member-specification, enumerator-list, or static data member or variable template initializer.

[ Note 1: In particular, the template arguments and names used in the function declarator (including parameter types, return types and exception specifications) can be private types or objects that would normally not be accessible. - end note]

(emphasis mine)

The code not compiling is due to a GCC bug 97942, and it compiles just fine in Clang. demo.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文