2016-11-01 1 views
2

Qu'est-ce qui empêche le fonctionnement de cette initialisation?Utilisation de l'opérateur de conversion pour initialiser une carte

#include <map> 
using std::map; using std::pair; using std::make_pair; 
struct P { 
    char a_, b_; 
    P(char a, char b) : a_{a}, b_{b} {} 
    operator pair<char,char>() { return make_pair(a_, b_); } 
}; 
int main() { 
    map<char,char> qmap { P('a','b') }; 
} 

Il ressemble à l'opérateur de conversion en P ne peut pas être appliquée implicitement dans une initialisier liste contreventement? Ou s'agit-il d'autre chose?

Répondre

3

Il peut, mais vous avez oublié le point clé: map 's value_type est en fait pair<const Key, Value>, donc dans votre exemple, vous auriez besoin de deux conversions (Ppair<char, char>pair<char const, char>) pour répondre à vos qmap' s value_type. C'est une conversion de plus que les règles permettent.

Si vous changez votre opérateur de conversion à

operator pair<char const,char>() { return make_pair(a_, b_); } 

votre code compiles.

+1

deux réponses en même temps. vous obtenez le "accepter" ... – towi

4

Notez que la partie clé d'un std::map est const, donc le type d'élément de std::map<char, char> est std::pair<const char, char>; le type ne correspond pas ici. Le std::pair<char, char> retourné avec des accolades ne peut pas être utilisé pour construire un std::initializer_list<std::pair<const char, char>>, (et ensuite construire un std::map<char, char> plus loin).

Si vous changez à

operator pair<const char,char>() { return make_pair(a_, b_); } 

ou

operator std::map<char, char>::value_type() { return make_pair(a_, b_); } 

le code fonctionnerait très bien.

+1

deux réponses en même temps. vous obtenez le "upvote" ... – towi