gpt4 book ai didi

c++ - 如何定义具有非尾随 decltype 返回类型的外联类模板成员函数

转载 作者:可可西里 更新时间:2023-11-01 18:38:54 27 4
gpt4 key购买 nike

template <class T>
struct foo {
int x;
decltype(x) f1();
};

似乎不可能定义f1 out-of-line。我尝试了以下定义,但均无效:

template <class T> decltype(x) foo<T>::f1() {}
template <class T> auto foo<T>::f1() -> decltype(x) {}
template <class T> auto foo<T>::f1() { return x; }
template <class T> decltype(std::declval<foo<T>>().x) foo<T>::f1() {}
// This return type is copied from the gcc error message
template <class T> decltype (((foo<T>*)(void)0)->foo<T>::x) foo<T>::f1() {}

这在实际代码中不是问题,因为将 f1 的类内声明更改为 auto f1() -> decltype(x); 允许第二个定义。但我很困惑为什么这会改变任何事情。甚至可以声明原始的 f1 不在线吗?

最佳答案

尽管这看起来很愚蠢,但我相信以下内容是正确的:

template <class T>
struct foo {
int x;
decltype(x) f1();
};

template <class T>
int foo<T>::f1() { return 0; }

Clang 接受它,但 GCC 不接受,所以我要说我认为 GCC 有一个错误。 [ Coliru link ]

问题是 f1 的这两个声明是否声明相同的函数(更专业地说,是同一类模板的相同成员函数)。这由 [basic.link]/9 管理,据此:

Two names that are the same (Clause 6) and that are declared in different scopes shall denote the same variable, function, type, template or namespace if

  • both names have external linkage or else both names have internal linkage and are declared in the same translation unit; and
  • both names refer to members of the same namespace or to members, not by inheritance, of the same class; and
  • when both names denote functions, the parameter-type-lists of the functions (11.3.5) are identical; and
  • when both names denote function templates, the signatures (17.5.6.1) are the same.

如果返回类型实际上是相同的(因为根据 [defns.signature.member.templ],返回类型是类成员函数模板的签名的一部分),要求似乎得到满足。自 foo<T>::xint , 它们是一样的。

如果 x 的类型不是这种情况被依赖。例如,GCC 和 Clang 在声明 x 时都拒绝定义。更改为 typename identity<T>::type x; . [ Coliru link ] 在这种情况下,[temp.type]/2 将适用:

If an expression e is type-dependent (17.6.2.2), decltype(e) denotes a unique dependent type. Two such decltype-specifiers refer to the same type only if their expressions are equivalent (17.5.6.1). [ Note: However, such a type may be aliased, e.g., by a typedef-name. — end note ]

也许 GCC 在考虑 x 时出错了依赖于类型(不应该)。但是,此注释提出了一种解决方法:

template <class T>
struct foo {
int x;
decltype(x) f1();
using x_type = decltype(x);
};

template <class T>
typename foo<T>::x_type foo<T>::f1() { return 0; }

这适用于 GCC 和 Clang。 [ Coliru link ]

关于c++ - 如何定义具有非尾随 decltype 返回类型的外联类模板成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49372823/

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