Вместо конструирования переменной-члена через конструктор - PullRequest
2 голосов
/ 19 апреля 2011

Возьмите следующий класс:

template <typename TPayload>
class Message
{
    public:
        Message(const TPayload& payload)
             : m_header(sizeof(TPayload)),
               m_payload(payload) {}

    private:
        const Header   m_header;
        const TPayload m_payload;
};

Всякий раз, когда я создаю Сообщение, мне нужно создать TPayload (параметр payload), скопировать его в m_payload и затем уничтожить полезную нагрузку. Теперь подумайте, что это можно сделать 100 000 раз в секунду, я думаю, что это потраченное впустую усилие.

У меня такой вопрос, могу ли я принудительно создать встроенную конструкцию m_payload, чтобы избежать временной полезной нагрузки?

Одним из возможных решений, которое я рассматриваю, является многократная перегрузка конструкции, как показано ниже, но, честно говоря, при копировании нескольких аргументов я сомневаюсь, что это значительно экономит.

template <typename TPayload>
class Message
{
    public:
        template <typename A>
        Message(const A& a)
             : m_header(sizeof(TPayload)),
               m_payload(a) {}

        template <typename A, typename B>
        Message(const A& a, const B& b)
             : m_header(sizeof(TPayload)),
               m_payload(a, b) {}

    private:
        const Header   m_header;
        const TPayload m_payload;
};

Ответы [ 2 ]

3 голосов
/ 19 апреля 2011

Что вам нужно, это пересылка аргументов конструктора, переданных Message в конструктор Message::m_payload.

Это можно сделать аккуратно в C ++ 11 (с использованием шаблонов переменных и std::forward, как используется в std::vector<>::emplace_back() и многих других функциях) или с несколькими перегрузками в C ++ 03, когда вы начали писать, и как б in boost::make_shared<>

например:

#include <iostream>
#include <string>
#include <utility>
typedef size_t Header;
template <typename TPayload>
class Message
{
    public:
        template <typename ...Args>
        Message(Args&&... args)
             : m_header(sizeof(TPayload)),
               m_payload(std::forward<Args>(args)...)
               {}
        void show_payload() const
        {
                std::cout << m_payload << '\n';
        }
    private:
        const Header   m_header;
        const TPayload m_payload;
};

int main()
{
     Message<std::string> test(10, 'a');
     test.show_payload();

     Message<double> test2(3.14);
     test2.show_payload();
}

тестовый прогон: https://ideone.com/J1JnZ

2 голосов
/ 19 апреля 2011

Также в C ++ 11 вы можете принять параметр по значению, а затем переместить построить его:

Message(TPayload payload)
    :m_header(sizeof(TPayload)),
     m_payload(std::move(payload)) {}

Просто убедитесь, что TPayload имеет правильно определенный и полезный конструктор перемещения, иначе это не принесет особой пользы.

...