接受类参数的友元函数的尾随返回类型
Trailing return type for a friend function that accepts class arguments
对于下面的代码:
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
};
我在decltype
里面y
下面有一个红色的波浪线,智能感知说cannot convert to incomplete class "person"
这到底是怎么回事?
注意:包括 ctor 和 dtor 在内的方法的定义在不同的翻译单元中。我想这不是这里错误的原因。
问题是因为即使decltype
的操作数可能是不完整的类型,用于形成充当操作数的 prvalue 的子表达式也是如此decltype
decltype(x+y);
相当于
decltype(operator+(x, y));
但person
在它自己的定义中是不完整的。您可以通过将operator+
定义为:
double operator+(person const&);
您可能会感兴趣的一些注释:
#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';
}
相关文章:
- 如何获取std::result_of函数的返回类型
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 函数作为模板参数,是否对返回类型强制约束
- C++中函数的向量返回类型引发错误
- 检查函数返回类型是否与STL容器类型值相同
- 警告:在函数返回类型 [-Wignore 限定符] 时忽略类型限定符
- 为什么 c++(g++) 不允许模板返回类型和函数名称之间有空格?
- 为什么返回类型的'const'限定符对标有 __forceinline/内联的函数没有影响?
- 在 c++ 中将函数返回类型指定为模板参数
- 使用 SWIG 更改生成的 CS 函数中的返回类型
- C++ 这里有一个返回 (24) 的布尔返回类型函数
- 使用SFINAE来检测void返回类型函数的存在
- 模板返回类型函数如何在C++中工作
- 如何在返回类型函数模板的专用化中使用派生类型?( "couldn't infer template argument" )
- Bon appetit :从 int 返回类型函数在 main() 中打印字符串
- 在引用或指针返回类型函数上输入
- 在后面的返回类型函数语法中,auto关键字背后是否有意图
- 我可以在c++中重写字符串返回类型函数吗?