С ++ Сбой без определения оператора - PullRequest
7 голосов
/ 20 октября 2011

В настоящее время я портирую приложение C ++ в слегка ограниченную среду.Приложение использует классы STL, string и stream.Я переписываю их упрощенные версии, которые будут хорошо играть в моей среде.

Меня беспокоит то, что мое приложение компилируется даже без всех необходимых определений операторов.Например, для моих строковых классов я определил:

string operator+ (const string& lhs, const string& rhs);

, и этого было достаточно.Тем не менее, я заметил, что часто были случаи, в которых mystring + «некоторая постоянная строка» нигде не определена.Когда я явно добавил его, оно использовалось:

string operator+ (const string& lhs, const char* rhs);

Что происходило до этого?Он успешно скомпилирован, прежде чем я добавил вторую функцию.Конечно, компилятор не сможет определить, как объединить строки в стиле c с моим классом строк.

Сейчас в моей программе странное поведение, и мне интересно, не связано ли это с другими оставленными операторамине определено.Есть ли способ заставить компилятор требовать такие определения операторов, если он нужен программе?

PS Мой класс строк находится в уникальном пространстве имен и не связан с std ::

Ответы [ 5 ]

12 голосов
/ 20 октября 2011

Невозможно быть уверенным, не увидев остальную часть вашего кода, но в этом случае, вероятно, нетрудно догадаться.У вас почти наверняка есть конструктор для вашего string, который принимает char const * в качестве своего параметра, поэтому происходит то, что компилятор использует этот ctor для преобразования char const * в string, а затем использует string operator+ (const string& lhs, const string& rhs); дляконкатенируйте это.

Разрешение на это является одной из (если не ) первичных причин перегрузки этих операторов глобальными, а не функциями-членами.В качестве функций-членов они могут преобразовывать правый операнд, но не левый.

2 голосов
/ 20 октября 2011

Есть ли в вашем классе 'string' конструктор с одним аргументом, который принимает const char *? Этот конструктор с одним аргументом помечен как «явный»?

Если он не явный, наиболее вероятный ответ заключается в том, что компилятор создает временный строковый объект из char * через конструктор преобразования, а затем использует эту временную строку для вызова вашего оператора сложения с двумя аргументами.

2 голосов
/ 20 октября 2011

Возможно, в вашем классе есть конструктор, который принимает const char * в качестве входного параметра. Скорее всего, этот конструктор используется для неявных покрытий и странного поведения, которое вы видите.

Объявите ваш конструктор, который принимает const char * как explicit, это отключит его использование для неявных преобразований, когда вы не собираетесь его использовать.

2 голосов
/ 20 октября 2011

Когда вы передаете const char*, строковый объект, вероятно, был создан и передан оператору +.Если вы выполните код в отладчике, вы, вероятно, сможете убедиться, что вызывается конструктор.

1 голос
/ 20 октября 2011

Компилятор не может знать, как преобразовать вашу строку в std::string или char*, если вы не укажете как.

Найдите конструкторы преобразования или операторы приведения в объявлении класса.

class MyString
{
    MyString(char*);
    MyString(std::string);

    operator std::string ();
    operator char*();
};

Они будут вызываться неявно.

Вы можете указать ключевое слово explicit для конструктора, чтобы этого не происходило.

Если это не решит проблему, выоператоры должны быть где-то перегружены, лучше всего найти, что они шагают по коду с помощью отладчика.

...