Вопрос по c++11, rvalue-reference, c++ – c ++ 11 оптимальная передача параметров

8

Рассмотрим эти классы:

#include <iostream>
#include <string>

class A
{
    std::string test;
public:
    A (std::string t) : test(std::move(t)) {}
    A (const A & other) { *this = other; }
    A (A && other) { *this = std::move(other); }

    A & operator = (const A & other)
    {
        std::cerr<<"copying A"<<std::endl;
        test = other.test;
        return *this;
    }

    A & operator = (A && other)
    {
        std::cerr<<"move A"<<std::endl;
        test = other.test;
        return *this;
    }
};

class B
{
    A a;
public:   
    B (A && a) : a(std::move(a)) {}
    B (A const & a) : a(a) {}
};

При созданииBУ меня всегда есть оптимальный путь впередA, один ход для значений или один экземпляр для значений.

Можно ли добиться того же результата с одним конструктором? В этом случае это не большая проблема, но как насчет множества параметров? Мне понадобятся комбинации всех возможных вхождений lvalue и rvalues в список параметров.

Это не ограничивается конструкторами, но также относится к параметрам функции (например, к установщикам).

Примечание: этот вопрос строго оclass B; class A существует только для визуализации того, как выполняются вызовы копирования / перемещения.

@JamesCuster: я просто хотел проверить, сколько раз вызывались соответствующие конструкторы / операторы. fscan
Вы должны прочитать это:stackoverflow.com/questions/8472208/… а такжеstackoverflow.com/questions/4782757/… James Custer

Ваш Ответ

3   ответа
9

Error: User Rate Limit Exceeded

class B
{
    A a;
public:   
    B (A _a) : a(move(_a)) {}
};

Error: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

class B
{
    A a;
public:   
    template <class T,
              class = typename std::enable_if
              <
                 std::is_constructible<A, T>::value
              >::type>
    B (T&& _a) : a(std::forward<T>(_a)) {}
};

Это вернет вас к оптимальному количеству конструкций копирования / перемещения. Но вы должны ограничить конструктор шаблона так, чтобы он не был слишком универсальным. Вы можете предпочесть использовать is_convertible вместо is_constructible, как я уже делал выше. Это также решение для одного конструктора, но когда вы добавляете параметры, ваше ограничение усложняется.

NoteError: User Rate Limit ExceededB получит неправильный ответ, когда они запросятstd::is_constructible<B, their_type>::value, Он будет ошибочно отвечать истине без надлежащего ограничения наB.

Я бы сказал, что ни одно из этих решений не всегда лучше, чем другие. Здесь должны быть сделаны технические компромиссы.

Error: User Rate Limit ExceededBError: User Rate Limit ExceededB::aError: User Rate Limit ExceededpublicError: User Rate Limit ExceededBError: User Rate Limit ExceededBError: User Rate Limit ExceededB b{ A() };Error: User Rate Limit ExceededB::aError: User Rate Limit ExceededB b{ a2 };Error: User Rate Limit ExceededB::aError: User Rate Limit Exceededa2Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded fscan
Error: User Rate Limit Exceeded fscan
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
2

Используйте выведенный тип параметра для конструктора дляB:

template <typename T> explicit B(T && x) : a(std::forward<T>(x) { }

Error: User Rate Limit ExceededA объект конструктивен

ЕслиAError: User Rate Limit Exceeded... везде.

Error: User Rate Limit Exceeded

1

Еслиstring в вашем образцеstd::stringError: User Rate Limit Exceededstd::stringError: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

A::A(string s) :test(std::move(s)) {}

Error: User Rate Limit Exceeded

class A
{
public:
    A() :p() {}

    A(const A& a) :p(new data(*a.p)) {} //copy
    A(A&& a) :p(a.p) { a.p=0; }         //move

    A& operator=(A a) //note: pass by value
    { clear(); swap(a); return *this; }
    ~A() { clear(); }

    void swap(A& a) { std::swap(p,a.p); }
    void clear() { delete p; p=0; }

private:

    data* p;
};

operator=Error: User Rate Limit Exceeded

class B: public A
{
...
};

Error: User Rate Limit Exceeded

Похожие вопросы