В C ++ у меня есть набор шаблонных функций variadi c, которые я хотел бы принять произвольное количество параметров, либо ссылки на константы, либо в качестве ссылок r-значения (поэтому я могу перемещать вещи, а не копировать, когда это возможно ). Однако я обнаружил, что версия, которая принимает ссылку на константу, вызывается, даже когда я оборачиваю аргументы в std::move()
.
// Accept end of parameters.
void example () {}
// Accept a non-constant R-value reference to do a move
template <typename... More>
void example (std::string &&value, More... parameters) {
std::cout << value << ": moved" << std::endl;
example (parameters...);
}
// Accept a constant reference parameter.
template <typename... More>
void example (const std::string &value, More... parameters) {
std::cout << value << ": copied" << std::endl;
example (parameters...);
}
int main (int, char **) {
std::string first { "first" };
std::string second { "second" };
std::string third { "third" };
std::cout << "Trying variadic with move as second parameter: " << std::endl;
example (first, std::move (second), third);
// std::cout << "Trying variadic with move as first parameter: " << std::endl;
// This next line won't even compile when uncommented
// example (std::move (first), std::move (second), third);
return 0;
}
Вывод:
Trying variadic with move as second parameter:
first: copied
second: copied
third: copied
вместо ожидаемое:
Trying variadic with move as second parameter:
first: copied
second: moved
third: copied
И в качестве бонуса, когда я оборачиваю первый аргумент в std::move()
, я получаю ошибку компиляции на g ++ 7 и clang 9.
Что я делаю не так?