Этот вопрос следует из Как пройти по лямбде в C ++ 0x? , но, возможно, это более понятный способ задать вопрос.
Рассмотрим следующее код :
#include <iostream>
#define LAMBDA(x) [&] { return x; }
class A
{
public:
A() : i(42) {};
A(const A& a) : i(a.i) { std::cout << "Copy " << std::endl; }
A(A&& a) : i(a.i) { std::cout << "Move " << std::endl; }
int i;
};
template <class T>
class B
{
public:
B(const T& x_) : x(x_) {}
B(T&& x_) : x(std::move(x_)) {}
template <class LAMBDA_T>
B(LAMBDA_T&& f, decltype(f())* dummy = 0) : x(f()) {}
T x;
};
template <class T>
auto make_b_normal(T&& x) -> B<typename std::remove_const<typename std::remove_reference<T>::type>::type>
{
return B<typename std::remove_const<typename std::remove_reference<T>::type>::type>(std::forward<T>(x));
}
template <class LAMBDA_T>
auto make_b_macro_f(LAMBDA_T&& f) -> B<decltype(f())>
{
return B<decltype(f())>( std::forward<LAMBDA_T>(f) );
}
#define MAKE_B_MACRO(x) make_b_macro_f(LAMBDA(x))
int main()
{
std::cout << "Using standard function call" << std::endl;
auto y1 = make_b_normal(make_b_normal(make_b_normal(make_b_normal(A()))));
std::cout << "Using macro" << std::endl;
auto y2 = MAKE_B_MACRO(MAKE_B_MACRO(MAKE_B_MACRO(MAKE_B_MACRO(A()))));
std::cout << "End" << std::endl;
}
, который выводит следующее:
Using standard function call
Move
Copy
Copy
Copy
Using macro
End
Ясно, что версия макроса каким-то образом исключает все вызовы конструктора перемещения / копирования, но версия функции не делает.
Я предполагаю, что в C ++ 0x есть синтаксически хороший способ удалить все ходы и копии без большого количества макросов, но я не могу понять это.
Причина:
Я планирую использовать такой код без ходов или копий для построения пакетов параметров, т. Е.
auto y = (_blah = "hello", _blah2 = 4);
f(y, (_blah3 = "world", _blah4 = 67));
И у них нет дополнительных ходов / копий по сравнению с некод параметра.