Как передать std :: move через шаблонный аргумент - PullRequest
1 голос
/ 11 марта 2020

Часто у меня будет шаблонная функция, в которой я пытаюсь передать тип &&. Проблема в том, что если в качестве аргумента указать std :: move, я получу такую ​​ошибку:

error: no matching function for call to 'doThing(void (*)(int&&), std::remove_reference<int&>::type)'

Код, сгенерировавший эту конкретную ошибку, выглядит следующим образом:

#include <utility>

template<typename T>
void doThing(void (*thing)(T), T input)
{
    thing(input);
}

void exampleThing(int&& someData)
{someData++;}

int main()
{
    int x, y = 5;
    exampleThing(std::move(x));             //compiles fine
    doThing(&exampleThing, std::move(y));   //error as shown above
}

Итак, как мне передать аргумент шаблону как ход?

1 Ответ

4 голосов
/ 11 марта 2020

Проблема с

template<typename T> void doThing(void (*thing)(T), T input)

в том, что T выводится из 2-х мест и должно быть идентичным.

Проще разделить на 2 параметра шаблона:

template <typename Arg, typename T>
void doThing(void (*thing)(Arg), T&& input)
{
    thing(std::forward<T>(input));
}

Демо

Другой вариант - разрешить удержание только в одном месте:

Я использую std :: type_identity (C ++ 20) для этого, но может быть тривиально повторно реализовано для предыдущей версии.

template <typename Arg>
void doThing(void (*thing)(Arg), std::type_identity_t<Arg> input)
{
    thing(std::forward<Arg>(input));
}

Демо

...