#include <iostream>
class B;
class A{
int a;
public:
friend void B::frndA();
};
class B{
int b;
public:
void frndA();
};
void B::frndA(){
A obj;
std::cout << "A.a = " << obj.a << std::endl;
}
int main() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
尝试编译此代码时,发生了一些错误.例如
无效使用不完整类型
这段代码有什么问题?
我有一个结构模板A<x>和一个+运算符int.
#include <iostream>
template<int x>
struct A{
int a;
};
template<int x>
int operator+(A<x> a, int b){
return a.a+b;
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个B<x>可转换为的结构模板A<x>.
template<int x>
struct B{
int b=3;
operator A<x>(){
return {b+10};
}
};
Run Code Online (Sandbox Code Playgroud)
现在我希望在打电话时B<x>转换成.A<x>B<x> + int
int main(){
std::cout<<(A<12>{9}+10)<<std::endl;//OK
std::cout<<(B<12>{9}+10)<<std::endl;//Error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在重载模板类的运算符时读取了隐式转换并写了
template<int x>
struct B{
int b=3;
operator A<x>(){
return {b+10};
}
friend int operator+(A<x> a, int b);
}; …Run Code Online (Sandbox Code Playgroud) 我想定义一个类模板的函数模板.代码看起来像这样.
template<int M>
struct test{
private:
int value;
template<int N = 2 * M>
friend auto foo(test const t){
test<N> r;
r.value = t.value;
return r;
}
};
int main(){
test<1> t;
foo(t);// expected to return test<2>
foo<1>(t);// expected to return test<1>
foo<3>(t);// expected to return test<3>
}
Run Code Online (Sandbox Code Playgroud)
但它不会编译.与以前的问题相比,下面列出了差异.
编译错误g++ -std=c++1z:
a.cpp: In instantiation of 'auto foo(test<M>) [with int N = 2; int M = 1]':
a.cpp:16:10: required from here
a.cpp:4:9: error: 'int test<2>::value' is private …Run Code Online (Sandbox Code Playgroud) c++ templates friend-function function-templates class-template
class baseClass {
public:
friend int friendFuncReturn(baseClass &obj) { return obj.baseInt; }
baseClass(int x) : baseInt(x) {}
private:
int baseInt;
};
class derivedClass : public baseClass {
public:
derivedClass(int x, int y) : baseClass(x), derivedInt(y) {}
private:
int derivedInt;
};
Run Code Online (Sandbox Code Playgroud)
在函数中friend int friendFuncReturn(baseClass &obj) { return obj.baseInt; }
我不明白为什么基类的友元函数适用于派生类?不应传递派生类 obj。而不是基类 obj。t 被视为错误?我的问题是为什么当我将派生类对象传递给它时它会起作用?
以下代码段:
struct a
{
[[nodiscard]] friend int b();
};
Run Code Online (Sandbox Code Playgroud)
产生在编译时这个错误clang++ (trunk 342102)有-std=c++17:
<source>:3:5: error: an attribute list cannot appear here
[[nodiscard]] friend int b();
^~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
删除friend或添加正文以b防止错误.
g++ (trunk) 编译代码就好了.
关于godbolt的实例:https://gcc.godbolt.org/z/ttTDuZ
这是一个clang++错误吗?或者标准中是否有一些规则使得此代码格式错误?
如果clang++是正确的,将friend成员函数标记为什么的正确方法是[[nodiscard]]什么?
如果我有一个普通的类,我可以在类中“注入”一个非自由的友元函数。(除其他外,只能由 ADL 找到)。
情况1:
class A{
double p_;
friend double f(A const& a){return a.p_;}
};
Run Code Online (Sandbox Code Playgroud)
如果这是一个模板类,我可以这样做:
案例2:
template<class T>
class A{
double p_;
friend double f(A const& a){return a.p_;} // apparently A const& is a synomyn for A<T> const&
};
Run Code Online (Sandbox Code Playgroud)
现在假设我需要f根据稍后需要定义的类来实现。我在这种情况下尝试这样做:
案例3:
template<class T>
class A{
double p_;
friend double f(A const& a);
};
...
Run Code Online (Sandbox Code Playgroud)
这已经给出了一个警告:“警告:朋友声明 'double f(const A&)' 声明了一个非模板函数 [-Wnon-template-friend]”。
按照编译器的建议,我可以这样做:
template<class T> class A;
template<class T> double f(A<T> const& a);
template<class T>
class A{
double p_; …Run Code Online (Sandbox Code Playgroud) c++ forward-declaration friend-function argument-dependent-lookup c++11
C++ 有一个特性,类内定义的友元函数只能通过 ADL(参数相关查找)找到:
struct Foo {
friend void fn(Foo) { } // fn can only be called by ADL, it won't be found by other lookup methods
};
Run Code Online (Sandbox Code Playgroud)
对于非友元函数是否可以实现相同的效果?我问这个问题是因为有时,我希望拥有“仅由 ADL 找到”的功能,但我实际上并不需要朋友访问类内部。
(还有一个有点固执己见的问题:如果这是不可能的,那么原因是什么?这个“仅由 ADL 发现”规则是故意设计到语言中的吗?)
c++ declaration friend-function name-lookup unqualified-name
考虑以下示例:
struct S {
template<typename T = void>
friend void foo(S) {
}
};
int main() {
S s;
foo(s); // (1)
foo<void>(s); // (2)
}
Run Code Online (Sandbox Code Playgroud)
我的 GCC 9.2.0 无法编译(2)并出现以下错误:
a.cpp: In function 'int main()':
a.cpp:10:5: error: 'foo' was not declared in this scope
10 | foo<void>(s);
| ^~~
a.cpp:10:9: error: expected primary-expression before 'void'
10 | foo<void>(s);
| ^~~~
Run Code Online (Sandbox Code Playgroud)
不过,(1)效果很好。为什么是这样?如何foo使用显式模板参数进行调用?
以下代码编译时没有任何错误,但它似乎破坏了 ODR:
#include <iostream>
template<long Num>
class B;
template<long Num>
struct A {
template<long Num1>
friend void ffoo(A<Num1> a, B<Num>* = nullptr) {
std::cout << "@A ffoo(A<" << Num1 << ">, B<" << Num << ">*)" << std::endl;
}
};
template<long Num>
class B {
public:
friend void ffoo(A<Num> a, B<Num>* = nullptr) {
std::cout << "@B ffoo(A<" << Num << ">, B<" << Num << ">*)" << std::endl;
}
};
int main() {
ffoo(A<1>{}); // @A ffoo(A<1>, …Run Code Online (Sandbox Code Playgroud) c++ templates one-definition-rule friend-function language-lawyer
考虑以下代码:
struct A
{
friend void foo(A& a) {}
};
struct B
{
void foo()
{
A a;
foo(a); // doesn't compile because "foo" friend function is hidden
}
};
int main()
{
A a;
foo(a); // OK here
}
Run Code Online (Sandbox Code Playgroud)
在函数中main,我可以轻松调用foo类内定义的友元函数A。
在函数中,B::foo相同的代码无法编译,因为友元函数通过其成员函数foo隐藏在类内部B。
有没有办法调用原来的隐藏函数而B不用重命名B::foo?我尝试使用::foo(a);orA::foo(a);但它们都不能编译。
c++ ×10
friend-function ×10
templates ×4
friend ×2
attributes ×1
c++11 ×1
c++14 ×1
c++17 ×1
class ×1
declaration ×1
inheritance ×1
name-lookup ×1