Take the following class:
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;
};
Whenever I construct a Message I have to create a TPayload (the parameter payload), copy this into m_payload, and then destruct payload. Now consider this can be done 100'000s of times a second, I think this is a 开发者_Go百科wasted effort.
My question is, can I force an inplace construction of m_payload to avoid the tempory payload?
One possible solution I am considering is overloading the construction many times like below but to be honest with all the copying of the multiple argumwents I'm doubting there is much saving.
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;
};
What you're looking for is forwarding of constructor arguments given to Message
to the constructor of Message::m_payload
.
This can be done neatly in C++11 (using variadic templates and std::forward
, as used in std::vector<>::emplace_back()
and many other functions) or with several overloads in C++03, as you started writing, and as used in boost::make_shared<>
for example:
#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();
}
test run: https://ideone.com/J1JnZ
Also in C++11, you can accept the parameter by value, then move construct it:
Message(TPayload payload)
:m_header(sizeof(TPayload)),
m_payload(std::move(payload)) {}
Just make sure TPayload has a properly defined and useful move constructor, otherwise this won't do much good.
精彩评论