У меня есть очень простой шаблон оболочки:
template<class T>
struct wrapper {
inline operator T () {
return v;
}
inline wrapper(T v):v(v) { }
T v;
};
Попытка использовать его с любым не примитивным типом с (например) оператором сравнения, основанным на определяемом им шаблоне, не выглядит многообещающим:
std::string t = "test";
assert(t == t);
typedef wrapper<std::string> string_wrapper;
assert(string_wrapper(t) == string_wrapper(t));
GCC 4.4.5 жалуется на эту ошибку:
error: no match for ‘operator==’ in ‘wrapper<std::basic_string<char> >(std::basic_string<char>(((const std::basic_string<char>&)((const std::basic_string<char>*)(& t))))) == wrapper<std::basic_string<char> >(std::basic_string<char>(((const std::basic_string<char>&)((const std::basic_string<char>*)(& t)))))’
Что интересно, GCC выполняет тройное приведение шаблона, а затем не использует operator ==
, который был определен для std::string
.
Я не думаю, что неявное принуждение невозможно, поскольку, если я изменю std::string
на int
или double
, bool
или что-нибудь примитивное, GCC выберет правильный оператор.
Я не хочу определять operator ==
для структуры оболочки, потому что этот оператор - всего лишь пример, и мне нужно wrapper
, чтобы «чувствовать» точно так же, как реальный тип относительно операторов.
Просто в приведении GCC неправильно понимает мой синтаксис, если я создаю оболочку и пытаюсь сравнить ее с собой, GCC снова жалуется (хотя и без тройного преобразования), что не может найти соответствующий оператор ==:
typedef wrapper<std::string> string_wrapper;
string_wrapper tw(t);
assert(tw == tw);
error: no match for ‘operator==’ in ‘tw == tw’
Почему GCC не может найти и / или использовать std::string operator == std::string
, когда wrapper
предоставляет приведение?