c++ - 接受类参数的友元函数的尾随返回类型
问题描述
对于以下代码:
using std::string;
class person
{
private:
string fname, lname;
double salary;
public:
person(string, string, double); // ctor declaration
~person(); // dtor declaration
double operator+(person);
friend auto salary_burden(person x, person y) -> decltype(x+y); // salary burden of two employees
};
我在y
里面有一个红色的波浪线decltype
,Intellisense 说cannot convert to incomplete class "person"
这是怎么回事?
注意:包括 ctors 和 dtors 在内的方法的定义在不同的翻译单元中。我想这不是这里错误的原因。
解决方案
您可能会觉得有趣的一些注释:
#include <string>
#include <iostream>
namespace humans
{
class person
{
private:
// certainly never write using namespace::thing in header files.
// if you are going to be using a type, do it in a very confined scope, in a cpp file
std::string fname, lname;
double salary;
public:
person(std::string, std::string, double); // ctor declaration
// you neither need or want a destructor for this class.
// if you define a destructor, you must also define copy & assignment
// operators. See rule of 5, 3 or none.
// define a way to see the salary
double get_salary() const { return salary; }
// there is no such thing as a person plus a person.
// avoid nonsensical mathematical abstractions
// double operator+(person);
};
// let's also provide a free function to get_salary, because it can be useful in ADL
auto get_salary(person const & p) -> decltype(p.get_salary())
{
return p.get_salary();
}
// salary_burden does not need to be a friend now that we
// have a way to get the salary. Since there is a free function available
// in the namespace of person, we could abstract this function a little more!
auto salary_burden(person const& x, person const& y) -> decltype(get_salary(x) + get_salary(y))
{
return get_salary(x) + get_salary(y);
}
}
// indeed in c++17 we could also abstract this concept completely...
template<class...Things>
auto salary_burden(Things&&...things)
{
// here whatever namespace Things is in, this namespace will be
// searched for a function called get_salary(Thing[&&|const&|&])
return (get_salary(things) + ...);
}
namespace non_humans
{
struct robot{};
// note that a robot does not have a get_salary() member
auto get_salary(robot const&) -> double { return 5; }
}
int main()
{
auto alice = humans::person("alice", "the programmer", 20000);
auto bob = humans::person("bob", "the builder", 10000);
auto robby1 = non_humans::robot();
auto robby2 = non_humans::robot();
auto robby3 = non_humans::robot();
// calls salary_burden(person const& x, person const& y)
std::cout << salary_burden(alice, bob) << '\n';
// calls auto salary_burden(Things&&...things)
std::cout << salary_burden(alice, bob, robby1, robby2, robby3) << '\n';
}
推荐阅读
- java - 没有尝试方法 IOException 的 BufferedWriter
- javascript - 我的代码中是否有任何错误,这不起作用,Jquery Ajax
- excel - 尝试使用 VBA 访问命名表以查找值
- javascript - 使用 JavaScript 渲染 Django HTML 标签
- c++ - Makefile:动态源文件名和对象目录
- java - 更改选项卡时自定义视图更改
- python - 如何使用 Python 从 cloudwatch 获取指标?
- postgresql - How to suspend PostgreSQL's ON_ERROR_STOP for just part of a psql script?
- linux - How to copy files with the same name in different source dir and rename in destination dir?
- matlab - 如何在 Matlab 中使用向量找到临界点 x 和 y?