c ++ 11 — неожиданное поведение std :: move для типа T * в переполнении стека

У меня есть ниже фрагмент кода, где я объявляю переменную с именем 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);
}

4

Решение

Поведение 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 определяется реализацией.

6

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

__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).

2

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