Проблема конверсии - PullRequest
       10

Проблема конверсии

1 голос
/ 02 ноября 2009

Я использую gcc 4.3.2.

У меня есть следующий код (упрощенно):

#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;
}

Выход компиляции:

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

Но есть c-tor, получающий const char *.

UDP:

Если я уберу явное из 1-го c-tor, я получу

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)’

Если я использую Foo (A (b.c_str ())), я получаю:

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)’

Ответы [ 2 ]

13 голосов
/ 02 ноября 2009

Ваш конструктор преобразования объявлен explicit. Ключевое слово explicit специально предназначено для предотвращения неявных преобразований этим конструктором. И неявное преобразование - это именно то, что вы ожидаете в своем коде (при вызове Foo).

Почему вы объявили свой конструктор explicit, если хотите, чтобы он работал в неявных преобразованиях?

3 голосов
/ 02 ноября 2009

A и B - абсолютно разные типы. Как отметил Андрей, не существует неявного вызываемого конструктора для преобразования. Вам придется написать

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

Это создаст временный «автоматический» (безымянный) объект типа A, использующий явный конструктор для const char. И это будет передано в Foo.

...