Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 类模板的友元函数是否应该成为所有实例化的友元?_C++_Templates_Language Lawyer_Friend Function - Fatal编程技术网

C++ 类模板的友元函数是否应该成为所有实例化的友元?

C++ 类模板的友元函数是否应该成为所有实例化的友元?,c++,templates,language-lawyer,friend-function,C++,Templates,Language Lawyer,Friend Function,考虑以下代码段: template<typename T> struct Foo { friend void bar(Foo, Foo<char> f) { static_cast<void>(f.private_field); // Should only compile when friends with Foo<char>. } private: int private_field{}; }; in

考虑以下代码段:

template<typename T> struct Foo {
    friend void bar(Foo, Foo<char> f) {
        static_cast<void>(f.private_field);  // Should only compile when friends with Foo<char>.
    }
private:
    int private_field{};
};

int main() {
    bar(Foo<char>{}, Foo<char>{});  // Compiles.
    bar(Foo<bool>{}, Foo<char>{});  // Compiles erroneously?
}
模板结构Foo{
好友无效栏(Foo,Foo-f){
static_cast(f.private_field);//应该只在friends with Foo时编译。
}
私人:
int私有_字段{};
};
int main(){
bar(Foo{},Foo{});//编译。
bar(Foo{},Foo{});//编译错误?
}
它使用trunk(截至2020年5月6日)GCC成功编译,但不使用Clang和MSVC:请参阅

谁在这里?

来自Clang和MSVC的错误消息如下所示:

<source>:3:29: error: 'private_field' is a private member of 'Foo<char>'

        static_cast<void>(f.private_field);  // Should only compile when friends with Foo<char>.

                            ^

<source>:11:5: note: in instantiation of member function 'bar' requested here

    bar(Foo<bool>{}, Foo<char>{});  // Compiles erroneously?

    ^

<source>:6:9: note: declared private here

    int private_field{};

        ^

1 error generated.

Compiler returned: 1
:3:29:错误:“private_field”是“Foo”的私有成员
静态_cast(f.private_字段);//应该只在朋友使用Foo时编译。
^
:11:5:注意:在这里请求的成员函数'bar'的实例化中
bar(Foo{},Foo{});//编译错误?
^
:6:9:注意:此处声明为私有
int私有_字段{};
^
生成1个错误。
返回的编译器:1

example.cpp
(3) :错误C2248:“Foo::private_字段”:无法访问类“Foo”中声明的私有成员
(6) :注意:请参见“Foo::private_字段”的声明
(2) :注:见“Foo”的声明
(2) :注意:编译类模板成员函数“void bar(Foo,Foo)”时
(11) :注意:请参阅正在编译的函数模板实例化“void bar(Foo,Foo)”的参考
(11) :注意:请参阅对正在编译的类模板实例化“Foo”的引用
返回的编译器:2

GCC在这里显然是错误的:因为每个专门化定义了自己单独的友元函数(因为它必须避免重复的定义错误),
bar(Foo,Foo)
Foo
的友元,但
bar(Foo,Foo)
不是。该标准包含了一个相关案例,其中提到了一个非常类似的案例

example.cpp

<source>(3): error C2248: 'Foo<char>::private_field': cannot access private member declared in class 'Foo<char>'

<source>(6): note: see declaration of 'Foo<char>::private_field'

<source>(2): note: see declaration of 'Foo<char>'

<source>(2): note: while compiling class template member function 'void bar(Foo<bool>,Foo<char>)'

<source>(11): note: see reference to function template instantiation 'void bar(Foo<bool>,Foo<char>)' being compiled

<source>(11): note: see reference to class template instantiation 'Foo<bool>' being compiled

Compiler returned: 2