Допустим у класса 'A' нужно реализовать метод get(), который сам вызывает оператор преобразования типа. clang и gcc без проблем компилируют этот код, но msvc выдает ошибку: 'error C3861: 'operator bool': identifier not found'
Не пойму в чём проблема, кто прав и что делать?
а не то, что у тебя.
Да, действительно. Просто минимизация понятие относительное и всегда боишься убрать лишнее.
σ>Прекратить выпендриваться и заменить A:: на this->
И в чем тут выпендривание, объясни?
Действительно, с this работает. Спасибо большое. Иногда получаешь проблему в таком неожиданном месте, что забываешь потыкать палочкой.
σ>Почитай стандарт, думаю, там найдётся ответ.
Да, так всё просто ?! Может тогда поможешь и укажешь точно на параграф?
V>Да, действительно. Просто минимизация понятие относительное и всегда боишься убрать лишнее.
Да не, минимизация — понятие вполне строгое.
Процесс, на выходе которого получается код, из которого нельзя убрать конструкций так, чтобы не сломать воспроизведение проблемы.
Ну максимум что-то для читабельности можно оставить, чтобы минимизация не превратилась в обфускацию.
σ>>Прекратить выпендриваться и заменить A:: на this-> V>И в чем тут выпендривание, объясни?
Да я просто так написал.
V>Действительно, с this работает. Спасибо большое. Иногда получаешь проблему в таком неожиданном месте, что забываешь потыкать палочкой.
Вообще вроде и без this-> должно, но не работает.
σ>>Почитай стандарт, думаю, там найдётся ответ. V>Да, так всё просто ?!
А ты думал.
V>Может тогда поможешь и укажешь точно на параграф?
Если время будет. Хотя смотреть в новые лукап-правила смысла может не иметь, они всё ещё слишком новые.
Здравствуйте, σ, Вы писали:
σ>Да не, минимизация — понятие вполне строгое.
Ок. Признаю, что оставил лишние детали, которые, как мне казалось, влияют на проблему.
σ>Вообще вроде и без this-> должно, но не работает.
Понятно, что ничего не понятно. Всю дорогу думал, что при отсутствии наследования и виртуальности метода, выражения эквивалентны:
// вызов минуя таблицу виртуальных функций (ломается на MSVC)
A::method();
this->A::method();
(*this).A::method();
// вызываем через таблицу виртуальных функций (если есть).
method();
this->method();
(*this).method();
В любом случае проблема решена и на этом спасибо. Может кто-нибудь еще потом объяснит в чем тут засада.
A specialization of a conversion function template is not found by name lookup. Instead, any conversion function templates visible in the context of the use are considered. For each such operator, if argument deduction succeeds ([temp.deduct.conv]), the resulting specialization is used as if found by name lookup.
Выходит, что работать должен и твой вариант, и даже без "A::", а просто: "return operator type_t()". Похоже, msvc просто не может разрулить между conversion function и conversion function template.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, Videoman, Вы писали:
V>Допустим у класса 'A' нужно реализовать метод get(), который сам вызывает оператор преобразования типа. clang и gcc без проблем компилируют этот код, но msvc выдает ошибку: 'error C3861: 'operator bool': identifier not found' V>Не пойму в чём проблема, кто прав и что делать?
Забавные ошибки выдает msvc, однако:
struct A
{
template <typename T>
operator T();
bool get() {
return operator bool(); // error C2352: 'A::operator T': a call of a non-static member function requires an object
}
};
То есть, он понимает, что 'A::operator T' — это нестатическая функция-член, но вот для какого она объекта вызвана — это загадка "со звездочкой"
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>... R>Выходит, что работать должен и твой вариант, и даже без "A::", а просто: "return operator type_t()". Похоже, msvc просто не может разрулить между conversion function и conversion function template.
Похоже ты прав и gcc и clang с тобой согласны.
Сейчас просто активно начал портировать код, что бы он работал одновременно и на Linux и на Windows, при том, что изначально код писался под Windows. Периодически наступаю на такие косяки, то с одной, то с другой стороны. Что интересно, MS в большинстве случаев работает в более расслабленном стиле, сам до всего догадывается и многое прощает, но видимо от этого и глючит в противоречивых, с точки зрения стандарта, случаях.
Здравствуйте, Videoman, Вы писали:
V>Сейчас просто активно начал портировать код, что бы он работал одновременно и на Linux и на Windows, при том, что изначально код писался под Windows. Периодически наступаю на такие косяки, то с одной, то с другой стороны. Что интересно, MS в большинстве случаев работает в более расслабленном стиле, сам до всего догадывается и многое прощает, но видимо от этого и глючит в неопределённых, с точки зрения стандарта, случаях.
Ну, тут ничего нового, к этому всегда нужно быть готовым
--
Не можешь достичь желаемого — пожелай достигнутого.
R>А я вот заморочился и поискал. И вот, что нашел: R>Выходит, что работать должен и твой вариант, и даже без "A::", а просто: "return operator type_t()".
Только вот это справедливо если ищется operator X, где X это конкретный тип.
Т.к. в `return operator type_t()`, даже с зависимым type_t, `operator type_t` это не dependent name, то должен [был] искаться, как я понимаю, литералли `operator type_t` (для какого-нибудь `struct type_t`) в template definition context. (https://cplusplus.github.io/CWG/issues/1500.html, https://godbolt.org/z/vjj3fGhzG)
Здравствуйте, σ, Вы писали:
σ>Только вот это справедливо если ищется operator X, где X это конкретный тип. σ>Т.к. в `return operator type_t()`, даже с зависимым type_t, `operator type_t` это не dependent name, то должен [был] искаться, как я понимаю, литералли `operator type_t` (для какого-нибудь `struct type_t`) в template definition context. (https://cplusplus.github.io/CWG/issues/1500.html, https://godbolt.org/z/vjj3fGhzG)
А разве согласно (1.3) 'operator type_t' не является зависимым именем?
P.S. Как, вообще, такое может быть — 'type_t' я вляется зависимым, а 'operator type_t' — нет?
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, σ, Вы писали:
R>>А разве согласно (1.3) 'operator type_t' не является зависимым именем?
σ>Посмотри в грамматику template-id
По здравому смыслу, это должно бы соответствовать operator-function-id, хотя, я вижу, что в списке операторов подходящего варианта для conversion function нет
--
Не можешь достичь желаемого — пожелай достигнутого.
R>>>А разве согласно (1.3) 'operator type_t' не является зависимым именем?
σ>>Посмотри в грамматику template-id
R>По здравому смыслу, это должно бы соответствовать operator-function-id, хотя, я вижу, что в списке операторов подходящего варианта для conversion function нет
operator T это conversion-function-id = `operator` conversion-type-id, оно вообще не может быть template-id, в смысле конструкция "conversion-function-id < template-argument-list[opt] >" невозможна, "< template-argument-list[opt] >" ушло бы в conversion-type-id
Здравствуйте, σ, Вы писали:
σ>operator T это conversion-function-id = `operator` conversion-type-id, оно вообще не может быть template-id, в смысле конструкция "conversion-function-id < template-argument-list[opt] >" невозможна, "< template-argument-list[opt] >" ушло бы в conversion-type-id
Да, я понимаю, возразить мне нечего. В то же время, то, что конструкция 'operator T' не является зависимой от 'T', не укладывается у меня в голове. То ли это упущение, то ли это закопано где-то в пластах формулировок, х.з.
P.S. Блин, че-то я тормознул, ты же ссылку дал на фикс, только сейчас обратил внимание. Т.е. dependent, все-таки. Спасибо.
--
Не можешь достичь желаемого — пожелай достигнутого.