gpt4 book ai didi

c++ - Friend 模板函数类内定义

转载 作者:太空狗 更新时间:2023-10-29 21:19:25 26 4
gpt4 key购买 nike

我不知道,为什么 gcc 会编译这段代码

#include <type_traits>

template<class Type, class ValueT>
class ImplAdd
{
template<typename T>
friend typename std::enable_if<std::is_same<T, ValueT>::value, Type>::type
operator+(T, T)
{
return Type{};
}
};

enum class FooValueT { ONE, ZERO };

class Foo : ImplAdd<Foo, FooValueT>
{
public:
Foo() {}
Foo(FooValueT) {}
};

struct A {};

int main()
{
Foo f = FooValueT::ONE + FooValueT::ZERO;
}

clang 和 msvc 无法编译,在我看来,它们是正确的。它是 GCC 编译器中的错误吗? gcc版本为4.8.2。

问题是由我的问题回答引起的:In-class friend operator doesn't seem to participate in overload resolution ,答案中引用了标准,指出这样的定义应该在类范围内,并且如果函数不是模板 - gcc 拒绝此代码,这是正确的。感谢您的回答,以及来自标准的引述,证明 gcc 是正确的(或不正确的)非常感谢。

最佳答案

我会说 GCC 错误地接受了这一点。引用 C++11,强调我的:

命名空间成员,7.3.1.2/3

Every name first declared in a namespace is a member of that namespace. If a friend declaration in a nonlocal class first declares a class or function the friend class or function is a member of the innermost enclosing namespace. The name of the friend is not found by unqualified lookup (3.4.1) or by qualified lookup (3.4.3) until a matching declaration is provided in that namespace scope (either before or after the class definition granting friendship). If a friend function is called, its name may be found by the name lookup that considers functions from namespaces and classes associated with the types of the function arguments (3.4.2). ...

参数相关查找,3.4.2/2:

For each argument type T in the function call, there is a set of zero or more associated namespaces and a set of zero or more associated classes to be considered. The sets of namespaces and classes is determined entirely by the types of the function arguments (and the namespace of any template template argument). Typedef names and using-declarations used to specify the types do not contribute to this set. The sets of namespaces and classes are determined in the following way:

  • ...
  • If T is an enumeration type, its associated namespace is the namespace in which it is defined. If it is class member, its associated class is the member’s class; else it has no associated class.
  • ...

3.4.2/4:

When considering an associated namespace, the lookup is the same as the lookup performed when the associated namespace is used as a qualifier (3.4.3.2) except that:

  • ...
  • Any namespace-scope friend functions or friend function templates declared in associated classes are visible within their respective namespaces even if they are not visible during an ordinary lookup (11.3).
  • ...

基于上述,我推断FooValueT(FooValueT::ONEFooValueT::TWO 的类型)有:: 作为关联的命名空间,但没有关联的类(因为它是一个枚举)。因此,在 ADL 期间不应考虑在类模板 ImplAdd 中定义的友元函数。

关于c++ - Friend 模板函数类内定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27418384/

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