2009-11-02 6 views
1

J'utilise gcc 4.3.2.Problème de conversion

J'ai le code suivant (simplifié):

#include <cstdlib> 

template<int SIZE> 
class Buffer 
{ 
public: 
    explicit Buffer(const char *p = NULL) {} 
    explicit Buffer(const Buffer &other); 

    const char *c_str() const { return m_buffer; } 

private: 
    char m_buffer[SIZE]; 
}; 

typedef Buffer<10> A; 
typedef Buffer<20> B; 

void Foo(A a) { 
} 

int main() 
{ 
    B b; 
    Foo(b.c_str()); // line 25 fails compilation 
    return 1; 
} 

rendements de compilation:

test.cpp: In function ‘int main()’: 
test.cpp:25: error: conversion from ‘const char*’ to non-scalar type ‘A’ requested 

Mais il y a c-tor réception const char *.

UDP:

Si je retire explicite du 1er c-tor je reçois

test.cpp: In function ‘int main()’: 
test.cpp:25: error: no matching function for call to ‘Buffer<10>::Buffer(A)’ 
test.cpp:7: note: candidates are: Buffer<SIZE>::Buffer(const char*) [with int SIZE = 10] 
test.cpp:25: error: initializing argument 1 of ‘void Foo(A)’ 

Si je Foo (A (b.c_str())) Je reçois:

test.cpp: In function ‘int main()’: 
test.cpp:25: error: no matching function for call to ‘Buffer<10>::Buffer(A)’ 
test.cpp:25: error: initializing argument 1 of ‘void Foo(A)’ 
+0

J'ai posté une question similaire mais dans un cas plus simple avec le même problème où il n'y a pas de distraction 'explicite'. http://stackoverflow.com/questions/7735107/how-do-i-fix-a-const-char-constructor-conversion-chain-error-in-gcc-compile – peterk

Répondre

13

Votre constructeur de conversion est déclaré explicit. Le mot-clé explicit est spécifiquement destiné à empêcher les conversions implicites de ce constructeur. Et une conversion implicite est exactement ce que vous attendez dans votre code (à l'appel Foo). Pourquoi avez-vous déclaré votre constructeur explicit, si vous voulez qu'il fonctionne avec des conversions implicites?

+0

Lorsque B est appelé Un type doit être construit à partir de b.c_str(), qui est const char *. Le 1er c-tor de A reçoit const char *, donc explicite ne devrait pas poser de problème ici. Est-ce que je manque quelque chose? – dimba

+1

Oui. 'explicite' signifie que le compilateur * ne le fera pas * exactement. Si vous supprimez explicitement, il sera capable de * implicitement * effectuer la conversion. – GManNickG

+2

@idimba: Vous passez un 'const char *' à une fonction qui attend 'A'. 'const char *' n'est pas 'A', donc une conversion est requise. Mais le compilateur ne peut pas utiliser le constructeur de conversion 'A :: A (const char *)', car il est déclaré 'explicite'. Si vous voulez que ce constructeur soit utilisé, vous devez épeler une conversion explicite 'Foo (A (b.c_str()))' – AnT

3

A et B sont des types totalement différents. Comme Andrey l'a souligné, il n'y a pas de constructeur implicable implicite pour la conversion. Vous devez écrire

Foo(A(b.c_str())); 

Cela va créer un objet (sans nom) « automatique » temporaire de type A l'aide du constructeur explicite pour const char. Et ce sera transmis à Foo.

+0

Ou supprimez 'explicit', j'ajouterais. – GManNickG