Почему я не могу использовать черты с пересылкой ссылок в C++?
У меня есть следующий тестовый код.
Смотрите 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 ответ
В стандарте существует специальное правило, касающееся удержания пересылочных ссылок. При заданном параметре переадресации T&&
, T
будет выведен как ссылка lvalue, если функция вызывается с lvalue.
Вы должны принять это во внимание в своих чертах:
Traits<std::remove_reference_t<E>>::value
Из стандарта:
http://eel.is/c++draft/temp.deduct.call#3
Ссылка для пересылки - это rvalue-ссылка на cv-неквалифицированный параметр шаблона, который не представляет параметр шаблона шаблона класса (во время вывода аргумента шаблона класса ([over.match.class.deduct])). Если P является ссылкой для пересылки, а аргумент является lvalue, тип "lvalue ссылка на A" используется вместо A для вывода типа.