У меня есть ниже фрагмент кода, где я объявляю переменную с именем pval
который пытается вывести T&&
на T*
[ с T
являющийся int
]. В соответствии с информацией о типе [декодированной с использованием abi] тип, полученный int*
,
Но когда я сравниваю int*
введите с decltype(pval)
он возвращает ноль, а не 1, что означает, что он лечит pval
как другой тип, кроме int*
, Так какой из них неправильный pval
являющийся int*
как сообщается typeid
или же is_same
что указывает на сравнение как ложное.
#include<iostream>
#include<string>
#include<typeinfo>
#include<cxxabi.h>
#include<type_traits>
using namespace std;
std::string classname(const std::type_info& info)
{
int status;
char* rslt=abi::__cxa_demangle(info.name(),0,0,&status);
std::string result(rslt);
free(rslt);
return result;
}
int main(int argc, char* argv[])
{
int* ptr = new int(10);
decltype(std::move(ptr)) pval = std::move(ptr);
cout << classname(typeid(pval)) << endl; // as per typeid information the type of pval is int*.
bool isSame = is_same<decltype(pval), int*>::value; // What then is the pval not same as int* as per is_same ?
cout << "isSame status = " << isSame << endl;
cout << is_same<int*, int*>::value << endl;
return(0);
}
Поведение decltype
а также typeid
разные.
Точный тип pval
является int* &&
то есть rvalue-ссылка на int*
, (Вот почему std::is_same
возвращается false
при сравнении с типом int*
.) По поведению decltype
,
если значение категории выражения равно xvalue, тогда decltype возвращает T&&;
И что std::move(ptr)
возвращается xvalue.
Следующие выражения являются выражениями xvalue:
- вызов функции или перегруженное выражение оператора, тип возвращаемого значения которого является rvalue ссылкой на объект, такой как
std::move(x)
;
Тогда дано decltype(std::move(ptr)) pval
, тип pval
было бы int* &&
,
С другой стороны, поведение typeid
это отличается.
Относится к
std::type_info
объект, представляющий типtype
, Еслиtype
является ссылочным типом, результат относится кstd::type_info
объект, представляющий ссылочный тип.
Это означает, что std::type_info
объект, возвращенный typeid(pval)
будет ссылаться на ссылочный тип, т.е. int*
не int* &&
,
Кстати: что std::type_info::name
Returns определяется реализацией.
__cxa_demangle()
Функция не дает вам надежную (или какую-либо?) информацию о константных и ссылочных квалификаторах. Попробуйте это вместо вашего classname()
функция:
template <typename T, bool WithCVCorrections = true>
std::string type_name()
{
typedef typename std::remove_reference<T>::type TR;
std::unique_ptr<char, void(*)(void*)> own(
abi::__cxa_demangle(typeid(TR).name(), nullptr, nullptr, nullptr),
std::free
);
std::string r = (own != nullptr) ? own.get() : typeid(TR).name();
if (WithCVCorrections) {
if (std::is_const<TR>::value)
r += " const";
if (std::is_volatile<TR>::value)
r += " volatile";
if (std::is_lvalue_reference<T>::value)
r += "&";
else if (std::is_rvalue_reference<T>::value)
r += "&&";
}
return r;
}
… который основан на коде Говарда Хиннанта Вот. Очевидное предостережение: это будет работать только для некоторых компиляторов (не MSVC).