Почему я не могу использовать черты с пересылкой ссылок в C ++? - PullRequest
0 голосов
/ 12 декабря 2018

У меня есть следующий тестовый код.

См. Godbolt https://godbolt.org/z/fLRM8d для исполняемого примера

template <typename T> struct Traits {
    static const bool value = false;
};

struct Zip{};
template <> struct Traits<Zip> {
    static const bool value = true;
};

template <typename E>
void Execute(E && e){
    static_assert(Traits<E>::value);
}

int main(){

    auto z = Zip();

    // Fails the static assertion with an lvalue
    Execute(z);

    // Passes the static assertion with an rvalue
    Execute(Zip());
}

Что здесь происходит, что я не могу использовать свой типчерта как я ожидаю?Как правильно моделировать эту проблему?

1 Ответ

0 голосов
/ 12 декабря 2018

В Стандарте существует специальное правило, касающееся удержания пересылочных ссылок.Учитывая ссылочную экспедиторскую параметр T&& T будет выведена как Lvalue ссылки если функция вызываются с именующим .

Вам необходимо учесть это в своих чертах:

Traits<std::remove_reference_t<E>>::value

живой пример на godbolt.org


Из Стандарта:

http://eel.is/c++draft/temp.deduct.call#3

Ссылка для пересылки - это rvalue-ссылка на cv-неквалифицированный параметр шаблона, который не представляет параметр шаблона шаблона класса(во время вывода аргумента шаблона класса ([over.match.class.deduct])).Если P является ссылкой для пересылки, а аргумент является lvalue, тип «lvalue ссылка на A» используется вместо A для вывода типа.

...