我的代码出了什么问题?
我试图在GNU G ++环境中编译下面的代码,我得到这些错误:
friend2.cpp:30: error: invalid use of incomplete type ‘struct two’ friend2.cpp:5: error: forward declaration of ‘struct two’ friend2.cpp: In member function ‘int two::accessboth(one)’: friend2.cpp:24: error: ‘int one::data1’ is private friend2.cpp:55: error: within this context
#include <iostream>
using namespace std;
class two;
class one
{
private:
int data1;
public:
one()
{
data1 = 100;
}
friend int two::accessboth(one a);
};
class two
{
private:
int data2;
public:
two()
{
data2 = 200;
}
int accessboth(one a);
};
int …Run Code Online (Sandbox Code Playgroud) 从书中做一些运动我遇到了疑问.我已经将一些运算符重载定义为类(Stonewt)的友元函数.问题来自这些原型:
friend ostream & operator<<(ostream &os, Stonewt &st);
friend Stonewt operator+(Stonewt &st1, Stonewt &st2);
Run Code Online (Sandbox Code Playgroud)
如果我依赖构造函数进行隐式转换并让编译器完成工作,如下所示(test1和test2是类对象):
cout << "Summing both weights: " << test1 + test2;
Run Code Online (Sandbox Code Playgroud)
我得到这样的错误消息:
无法将'std :: basic_ostream'左值绑定到'std :: basic_ostream &&'
初始化'std :: basic_ostream <_CharT,_Traits>&std :: operator <<的参数1(std :: basic_ostream <_CharT,_Traits> &&,const _Tp&)[with _CharT = char; _Traits = std :: char_traits; _Tp = Stonewt]'
OTOH,如果我执行以下操作,我不会收到任何错误:
Stonewt test3 = test1 + test2;
cout << "Summing both weights: " << test3;
Run Code Online (Sandbox Code Playgroud)
就像编译器获得Stonewt对象一样,它可以转换为Stonewt&(这就是函数所期望的).但如果它得到了其他的东西,它就无法到达Stonewt&.(同样的事情发生在其他运算符重载的其他实例中,如operator*,如果我放一个double并期望编译器通过构造函数将其转换为Stonewt然后到Stonewt&,它不起作用.我必须放一个Stonewt宾语).
我会把整个程序放在你需要的地方:
班级定义:
// stonewt1.h -- revised …Run Code Online (Sandbox Code Playgroud) c++ compiler-errors operator-overloading friend-function implicit-conversion
当友元函数 mag() 在类内部定义时,下面显示的代码不会编译,但如果在类外部定义(已注释),则可以工作。我认为差异是由用于将参数类型从 A 更改为 B 的复制构造函数引起的。有人可以解释为什么我应该在外部定义友元函数吗?
而且,如果B类是模板类(template <class T>在最上面添加),在外面定义友元函数也是不行的。
#include <iostream>
using namespace std;
class A {
};
class B {
public:
B(const A& p) {
std::cout << "Copy/Conversion constructor" << std::endl;
}
friend void mag(const B& p) {
std::cout << "Mag Inside`.\n";
}
};
//void mag(const B& p) {
// std::cout << "Mag Outside.\n";
//}
int main() {
A a;
mag(a);
return 0;
}
Run Code Online (Sandbox Code Playgroud) Sales_data.h
#ifndef SALES_DATA_H
#define SALES_DATA_H
#include <string>
class Sales_data {
friend std::istream &read(std::istream &in, Sales_data &data);
friend std::ostream &print(std::ostream &out, const Sales_data &data);
public:
Sales_data() = default;
//Sales_data(std::string _bookNo="", unsigned _units_sold = 0, double _revenue = 0)
//:bookNo(_bookNo), units_sold(_units_sold), revenue(_revenue) {}
std::string isbn() { return bookNo; }
Sales_data& combine(const Sales_data&);
double avg_price() const;
private:
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0;
};
Sales_data &Sales_data::combine(const Sales_data& data) {
units_sold += data.units_sold;
revenue += data.revenue;
return *this;
}
std::istream …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个包含迭代器的容器.例如,它创建了间接范围.我希望范围的迭代器取消引用底层迭代器.我做到了,但后来我需要关系运算符.以下是重现问题的简化版本:
template <typename T>
struct foo
{
class bar
{
friend bool do_something(bar);
};
bar get_bar()
{
return bar{};
}
};
template <typename T>
bool do_something(typename foo<T>::bar)
{
return true;
}
#include <iostream>
int main()
{
foo<int> f;
auto b = f.get_bar();
std::cout << do_something(b);
}
Run Code Online (Sandbox Code Playgroud)
/tmp/prog-c08a3a.o:在函数
main': prog.cc:(.text+0x12): undefined reference todo_something(foo :: bar)'
这是我得到的唯一错误.
在类中声明了什么以及在类之外定义为自由函数的是什么?
编译器要求我放一个模板,但这显然不是我想要的.我不希望与一种ForwardIterator类型相关的迭代器与另一种ForwardIterator类型的迭代器相比.但我认为没问题,让我们尝试一下,但它给了我阴影错误,这加强了我的怀疑.
从我所听到的,在里面定义它将使它只能ADL可调用.有些IDE可能没有想到这一点,所以我认为在外面声明它们会更好.
我有一个简单的C++类,我正在尝试添加流操作符,因此它可以与cout和一起使用cin
#include <iostream>
namespace testing_namespace {
class test {
friend std::ostream &operator<<(std::ostream &os, const test &o);
friend std::istream &operator>>(std::istream &is, test &o);
public:
void doThing();
private:
int member;
};
}
Run Code Online (Sandbox Code Playgroud)
这是实现文件:
std::ostream &operator<<(std::ostream &os, const testing_namespace::test &o) {
return os << o.member;
}
std::istream &operator>>(std::istream &is, testing_namespace::test &o) {
return is >> o.member;
}
void testing_namespace::test::doThing() {
std::cout << member << " thing" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我在编译时遇到错误:
In function 'std::ostream& operator<<(std::ostream&, const testing_namespace::test&)':
test.cpp:8:20: error: 'int testing_namespace::test::member' …Run Code Online (Sandbox Code Playgroud) /** module.h */
#pragma once
class A {
friend void helpers::logValue(const A &);
int _val;
public:
A() {}
};
namespace helpers {
static void logValue(const A &a) {
std::cout << a._val; // <== ERROR: '_val' is not accessible
}
}
Run Code Online (Sandbox Code Playgroud)
如何在另一个命名空间中声明友元函数?
我有一个模板化的Stack类,内部使用vector实现.
这是我(简化)TStack.h的内容:
#include <vector>
#include <iostream>
template<typename T> class TStack;
template<typename T> TStack<T> operator+(const TStack<T> &s1, const TStack<T> &s2);
template<typename T>
class TStack {
friend TStack<T> operator+<>(const TStack<T> &s1, const TStack<T> &s2);
private:
std::vector<T> items;
public:
void printAll() {
std::cout << "The content of the stack is: ";
typename std::vector<T>::iterator it;
for(it = items.begin(); it < items.end(); it++) {
std::cout << *it << " ";
}
std::cout << std::endl;
}
};
template<typename T>
TStack<T> operator+(const TStack<T> &s1, const TStack<T> &s2) …Run Code Online (Sandbox Code Playgroud) 我最近了解到有两种方法可以声明模板友元类或函数.例如,要声明模板好友类,您可以执行此操作
template <typename T>
class goo
{
template <typename T>
friend class foo;
};
Run Code Online (Sandbox Code Playgroud)
或这个
template <typename T>
class goo
{
friend class foo <T>;
};
Run Code Online (Sandbox Code Playgroud)
这两个声明实际上是不同的.前者允许您使用任何类型的模板朋友类foo与任何类型的模板朋友类goo.后者只允许您使用相同的类型,以便您可以foo<int>使用goo<int>但不能foo<int>使用goo<char>.
在下面的头文件中,我尝试使用后一种形式的声明来使我的模板友元函数friend std::ostream& operator<<(std::ostream&, const Array<T>&);更具特定于类型,以使我的程序更加封装.
Run Code Online (Sandbox Code Playgroud)#include <iostream> #include "Animal.h" const int DefaultSize = 3; template <typename T> // declare the template and the paramenter class Array // the class being parameterized { public: Array(int itsSize = DefaultSize); Array(const Array &rhs); ~Array() …
以下代码class Foo在namespace Namespace.
// main.cpp
#include <csignal>
namespace Namespace
{
class Foo
{
private:
void doSomething() {};
friend void func( union sigval );
};
}
static Namespace::Foo foo;
void func( union sigval sv ) {
(void)sv;
foo.doSomething();
}
Run Code Online (Sandbox Code Playgroud)
我想和void func( union sigval )这个类交个朋友,这样它就可以调用一个私有函数。执行此操作的正确语法是什么?以上失败并出现以下错误:
$ g++ --version && g++ -g ./main.cpp
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. …Run Code Online (Sandbox Code Playgroud) c++ ×10
friend-function ×10
templates ×4
friend ×2
namespaces ×2
c++11 ×1
c++17 ×1
clang++ ×1
g++ ×1
syntax ×1