Рассмотрим следующий фрагмент:
struct Base { };
struct Derived : Base { };
void f(Base &) { std::cout << "f(Base&)\n"; }
template <class T = int>
void g() {
Derived d;
f(T{} ? d : d); // 1
}
void f(Derived &) { std::cout << "f(Derived&)\n"; }
int main() {
g();
}
В этом случае я считаю, что вызов функции f в // 1 следует искать на первом этапе, поскольку тип его аргумента однозначно Derived&, и, таким образом, разрешаться в f(Base&), который является единственным в области видимости.
Clang 3.8.0 со мной согласен, но GCC 6.1.0 этого не делает и откладывает поиск f до второй фазы, где будет найден f(Derived&).
Какой компилятор прав?
fвнезапно изменился и включил больше кандидатов, если я изменю условное выражение наT{} ? d : eв какой-то момент в будущем. Особенно, еслиeявляется ссылкой, которая инициализируется с помощьюd, но может измениться, чтобы ссылаться на что-то другое в будущем. Кроме того, возможность форсировать зависимое разрешение имени для вызова функции с использованием чего-то вродеf((always_void<T>() , arg)), даже еслиargне является зависимым, кажется мне скорее функцией, чем ошибкой. - person bogdan   schedule 01.06.2016noexcept(T{} ? d : d), не зависящими от значения, что было бы неправильно (конструкторTможет throw), поэтому необходимо добавить некоторые дополнительные особые случаи. Не уверен, что оно того стоит, но теперь я думаю, что стоит задуматься. Чем больше я думаю об этом, тем интереснее становится твой вопрос! - person bogdan   schedule 01.06.2016noexcept(typeid(T{}))также не зависит от значения. - person Columbo   schedule 01.06.2016throwпросто не вырезал, не так ли? Хорошая находка, хотя в вашем конкретном примере правильность не затрагивается (T{}всегда является значением prvalue, поэтому оно не оценивается иtypeidне может выбрасывать), тогда как для условного это было бы. Однако дляtemplate<class T> void f(T& t) { constexpr bool n = noexcept(typeid(t)); }у нас есть проблема; Я думаю, что вы только что нашли здесь незаметную стандартную ошибку. И Clang, и GCC рассматривают его как зависящее от значения, хотя GCC неправильно устанавливает его наtrueво всех случаях. - person bogdan   schedule 01.06.2016