шаблоны — уточнение хотел повторно. C ++ type_traits

Похоже, что для проверки на константу необходимо проверить параметр-шаблон, но для проверки на rvalue-ness необходимо проверить фактический параметр. (Это использует VC ++ 2012.) Этот код иллюстрирует то, что я имею в виду:

#include <type_traits>
#include <string>
#include <iostream>

using namespace std;

template<class T>
void f(T& x) {
cout << "f() is_const<T> and is_const<decltype<x)>" << endl;
cout << is_const<T>::value << endl; // Prints 1 when arg is const
cout << is_const<decltype(x)>::value << endl; // Prints 0 when arg is const
}

template<class T>
void g(T&& x) {
cout << "g() is_const<T> and is_const<decltype<x)>" << endl;
cout << is_const<T>::value << endl; // Prints 0 when arg is const
cout << is_const<decltype(x)>::value << endl; // Prints 0 when arg is cons
cout << "g() is_rvalue_reference<T> and is_rvalue_reverence<decltype(x)>" <<endl;
cout << is_rvalue_reference<T>::value << endl; // Prints 0 when arg is rvlaue
cout << is_rvalue_reference<decltype(x)>::value << endl; // Prints 1 when arg is rvalue
}

int main()
{
const std::string str;
f(str); // const argument
cout << endl;
g(std::string("")); // rvalue argument
return 0;
}

Я изо всех сил пытаюсь понять, почему это так. Может кто-нибудь объяснить или указать мне статью, которая это объясняет? При необходимости я буду копаться в стандарте C ++ 11. Кто-нибудь знает соответствующие разделы?

1

Решение

Причина в том, что вы неправильно понимаете вещи. x никогда не будет const в любом из этих примеров, просто потому что нет const ссылочные типы (вы не можете изменить то, на что ссылается ссылка в любом случае). В is_const<T> вы в основном игнорируете, что вы объявили x как T&,

Похожее недоразумение работает для контрольного теста rvalue. T в T&& (который называется универсальной ссылкой, кстати) будет выведен как U& когда вы передаете lvalue и как U когда вы передаете значение. При тестировании is_rvalue_reference<T>опять игнорируешь, что объявил x как T&&, При тестировании is_const<T>Вы не учли тот факт, что T будет ссылка, которая, как сказано выше, никогда не может быть const,

Правильные тесты для g было бы

  • std::is_const<typename std::remove_reference<T>::type>::value а также
  • std::is_rvalue_reference<T&&>::value
5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]