2010-07-01 4 views
3

Edit:adresse de retour variable locale ou temporaire lorsque vous utilisez C++ 0x decltype valeur retournée

Ceci est en effet un bogue dans le compilateur, je l'ai ouvert un defect et a obtenu la réponse suivante.

Bonjour Motti,
Nous vous remercions de soumettre cette question. Comme indiqué dans la publication de stackoverflow, il s'agit d'un bug dans notre implémentation decltype. Malheureusement, nous ne pouvons pas corriger ce bug dans la prochaine version de Visual Studio car le code est relativement rare, et nous sommes particulièrement limités en ressources.

question originale suit


Je joue un peu avec les C++ 0x caractéristiques VS10 et je suis tombé sur le problème suivant.

std::map<int, int> map() 
{ 
    return std::map<int, int>(); 
} 

template <class F> 
auto call(F f) -> decltype(f()) 
{  
    auto ret = f(); 
    return ret; 
} 

void check() 
{ 
    auto m = call(map); 
} 

Je reçois l'avertissement suivant:

avertissement C4172: adresse de retour de la variable locale ou temporaire

Cependant quand je change le prototype de call être le style ancien:

std::map<int, int> call(F f) 

C'est bon, c'est aussi OK quand call n'est pas une fonction de modèle (même en utilisant des types de retour déduits). Si je regarde le type de ret c'est std::map<int, int> (pas de références ou de pointeurs).

Est-ce un bug dans VS10 ou est-ce que je manque quelque chose?

+0

Est-ce que le débogueur vous dira quel type '' auto ret' résout? Je sais qu'il y a des différences entre la façon dont 'auto' et' decltype' se comportent, mais je n'ai aucune idée si cela cause le problème ... – Cogwheel

+0

FWIW, Comeau aboie à 'auto' précédant' call() '. (Bien sûr, je n'ai aucune idée de qui est juste ici ...) – sbi

+0

@sbi avec C++ 0x allumé? – Motti

Répondre

3

call(map); convertit implicitement carte à un pointeur de fonction, pour rendre la fonction:

auto call(std::map<int,int>(*f)()) -> decltype(f()) 

On dirait que VC10 ne répond pas pour decltype, C++ 0x FCD qui dit:

Le type désigné par decltype (e) est défini comme suit:

  • si e est un sans parenthèses id-expression ou une classe mem sinon, si 0 est un appel de fonction (5.2.2) ou [snip], decltype (e) est le type de retour de la fonction choisie statiquement; Sinon, si e est une lvalue, le type déclaré (e) est T &, où T est le type de e;

  • sinon, decltype (e) est le type de e.

5.2.2 montre clairement que l'appel par un pointeur de fonction est un « appel de fonction » si decltype(f()) doit être std::map<int,int>. Au lieu de cela, il traite f() comme une expression lvalue, avec le résultat std::map<int,int> &. Le type de ret est déduit correctement, mais il est jeté dans une référence par le retour.

Ce bogue n'apparaît pas lorsque vous utilisez une expression de fonction au lieu d'une expression de pointeur de fonction, decltype(map()) aboutit correctement à std::map<int,int>.

Questions connexes