Dans cette ligne:Quel est le type exact de "" lorsque déduit par `auto`?
auto a = "Hello World";
Quelle est la exacte Type de a
? Je devinerais char[]
ou const char* const
mais je ne suis pas sûr.
Dans cette ligne:Quel est le type exact de "" lorsque déduit par `auto`?
auto a = "Hello World";
Quelle est la exacte Type de a
? Je devinerais char[]
ou const char* const
mais je ne suis pas sûr.
N4296 2.13.5/8
chaînes littérales ordinaires et les littéraux de chaîne UTF-8 sont également appelés à chaînes littérales aussi étroites. Une chaîne littérale étroite a le type "tableau de n const char", où n est la taille de la chaîne définie ci-dessous, et a une durée de stockage statique (3.7).
Mais comme la variable est initialisée comme dans votre code, elle est en réalité const char*
, vous pouvez le vérifier comme ceci.
template<typename> struct TD;
int main()
{
auto a = "Hello World";
TD<decltype(a)> _;
}
seront ici Erreur de compilation dans laquelle vous pouvez voir le type de TD
instance réelle, quelque chose comme ça avec clang
error: implicit instantiation of undefined template 'TD<const char *>'
N4296 7.1.6.4
Si l'espace réservé est le spécificateur de type automatique, le type déduit est déterminé en utilisant les règles pour la déduction d'argument de modèle.
template<typename> struct TD;
template<typename T>
void f(T)
{
TD<T> _;
}
int main()
{
auto c = "Hello";
TD<decltype(c)> _;
f("Hello");
}
Les deux objets instanciés de type TD
a pour type TD<const char*>
.
N4926 14.8.2.1
déduction argument du modèle se fait en comparant chaque fonction type de paramètre de modèle (appelons-P) avec le type de l'argument correspondant de l'appel (appeler A) tel que décrit au dessous de.
Si P est pas un type de référence:
Si A est un type de réseau, le type de pointeur produite par la conversion standard à matrice pointeur (4,2) est utilisé à la place de A pour déduction de type
* "vous pouvez le vérifier comme ceci" TD
@TonyD le fait est qu'un type incomplet déclenche une erreur de compilation qui affiche le type utilisé pour instancier ce type incomplet. Une solution plus pratique est 'template
@TonyD c'est vérifier. Ne pas définir TD. Vous allez voir le type de TD à la compilation comme erreur de compilation. – ForEveR
Sauf si vous avez des raisons de penser que ce serait la mise en œuvre ou non défini, pouvez tester:
#include <iostream>
template <typename T> void f() { std::cout << "other\n"; }
template <> void f<const char*>() { std::cout << "const char*\n"; }
template <> void f<const char* const>()
{ std::cout << "const char* const\n"; }
template <> void f<const char(&)[12]>() { std::cout << "const char[12]\n"; }
int main()
{
auto a = "Hello World";
f<decltype(a)>();
}
sortie:
const char*
Vérifier que ++a
est un autre indice compile (il fait), et alors que la mise en œuvre définie #include <typeinfo>
/typeid(a).name()
peut souvent aider à répondre à ces questions.
Passez à auto& a
et vous verrez a
changements à const char(&)[12]
.
Vous pouvez imprimer le type de l'aide typeinfo
int main()
{
auto a = "Hello World";
std::cout << "type is: " << typeid(a).name() << '\n';
}
sur gcc il imprimera
pi est: PKc
qui signifie pointeur vers un char constant Si vous êtes dans Windows la sortie sera beaucoup plus lisible, mais vous vous habituerez à cette syntaxe aussi.
Si vous en savez plus ou moins que vous tapez une nouvelle recherche, vous pouvez également vérifier si deux types sont équivalents:
#include <typeinfo>
std::cout << std::is_same<const char*, decltype(a)>::value << std::endl;
Utilisez C++ filt pour démêler les noms. Quoi qu'il en soit, typeid n'est pas le meilleur pour montrer les types car il élimine les qualificatifs cv. – edmz
Vous avez raison, je ne le savais pas, j'ai été troublé par le fait que 'char * b = const_cast
Je ne recommanderais pas typeid.name qui peut retourner les mauvais types comme Scott Meier explique à http://www.aristeia.com/TalkNotes/C++TypeDeductionandWhyYouCareCppCon2014.pdf (Diapositive 32) – Guillermo
De cette façon, il se désintègre à 'const char *' –
On dirait 'const char * ', sur ma version de g ++ (4.8.1), à la fois' typeid (a) .name() 'et' typeid (const char *). name() 'retourne la même valeur alors que' typeid (const char [ ]). name() 'ou' typeid (b) .name() '(' const char b [] = "Bonjour tout le monde"; ') retourne quelque chose d'autre. – Holt