Завершающий тип возврата для функции-друга, которая принимает аргументы класса - PullRequest
0 голосов
/ 29 декабря 2018

Для приведенного ниже кода:

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, находятся в другой единице перевода.Я думаю, что это не является причиной ошибки здесь.

Ответы [ 2 ]

0 голосов
/ 29 декабря 2018

Некоторые заметки, которые могут вас заинтересовать:

#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';
}
0 голосов
/ 29 декабря 2018

Проблема заключается в том, что даже когда операнд decltype может иметь неполный тип, то же самое не распространяется на подвыражения, используемые для формирования значения, действующего как операнд decltype

decltype(x+y);

эквивалентно

decltype(operator+(x, y));

, но person является неполным в своем собственном определении.Вы можете обойти это, определив operator+ как:

double operator+(person const&);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...