Link-Zeitlösung:
Auf meiner Plattform (O X), kann ich den Linker hol mir, indem einfach ein kurzes Programm, diese Informationen zu geben, die abgeschlossen ist, minus der Definition der Funktion I‘ m gespannt:
template<typename T>
void f(T&& parameter); // purposefully not defined
int
main()
{
const volatile int * const pInt = nullptr;
f(pInt);
}
Undefined symbols for architecture x86_64:
"void f<int const volatile* const&>(int const volatile* const&&&)", referenced from:
_main in test-9ncEvm.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Zwar habe ich die „triple Referenz“, die als L-Wert-Referenz (wegen Referenz Kollabieren) interpretiert werden sollen, und ist ein Demangling Bug (vielleicht kann ich das fest).
Laufzeit Lösung:
Ich halte eine type_name<T>()
Funktion praktisch für diese Art der Sache. Ein komplett portabler ist möglich, aber für mich suboptimal. Hier ist sie:
#include <type_traits>
#include <typeinfo>
#include <string>
template <typename T>
std::string
type_name()
{
typedef typename std::remove_reference<T>::type TR;
std::string r = typeid(TR).name();
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;
}
Ich mag es verwenden können:
#include <iostream>
template<typename T>
void f(T&& parameter)
{
std::cout << type_name<T>() << '\n';
}
int
main()
{
const volatile int * const pInt = nullptr;
f(pInt);
}
die für mich ausdruckt:
PVKi const&
Das ist nicht besonders freundlich Ausgang ist. Deine Erfahrung ist vielleicht besser. Meine Plattform ABI basiert auf der Itanium ABI. Und das ABI enthält diese Funktion:
namespace abi
{
extern "C"
char*
__cxa_demangle(const char* mangled_name, char* buf, size_t* n, int* status);
}
Ich kann diese verwenden C++ Symbole in eine für Menschen lesbare Form demangle.Ein type_name<T>()
aktualisiert nutzen hierfür ist:
#include <type_traits>
#include <typeinfo>
#include <string>
#include <memory>
#include <cstdlib>
#include <cxxabi.h>
template <typename T>
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 (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;
}
Und nun die vorherigen main()
druckt:
int const volatile* const&
möchten Sie dies während der Kompilierung oder zur Laufzeit? letzteres kann mit '#include' und 'typeid (T) .name()' –
TemplateRex
'std :: is_same :: value'? –
Rapptz
@TemplateRex: Ich möchte den Typ während der Kompilierung sehen. – KnowItAllWannabe