sfinae с decltype: ошибка в clang или gcc?

Clang-3.2 может компилировать и код вести себя как положено:

struct have_f { int f(int i) {return 10;} }; 

struct empty {};

template  
struct outer {
        T t; 

        // if T have f(), define  outer_f()
        template 
        int outer_f(int i) { return t.f(i); }
};

int main() {
        outer  o1;
        outer   o2;

        // to silence unused var warning
        return  o1.outer_f(10) + sizeof(o2); 
}

GCC любой версии отклоняется с:

t.cc:13:6: error: ‘struct empty’ has no member named ‘f’
  int outer_f(int i) { return t.f(i); }
      ^

Кто прав? GCC или Clang?

Обратите внимание, что там былоаналогичный вопросбез реального ответа.

 Luc Danton10 окт. 2012 г., 10:59
Я не могу сказать вам, должен ли код быть отклонен или нет, и я нене знаю, если вы заинтересованы в прагматических обходных путей, но я знаю, чтоT 'зависимый» снова гарантирует, что GCC выполняет SFINAE:.template
 nijansen10 окт. 2012 г., 08:38
@SingerOfTheFall Я согласен с вами, но вопрос не в том, почему он не работает, а в том, какой компилятор соответствует стандарту.
 Matthieu M.10 окт. 2012 г., 08:44
@SingerOfTheFall: Вопрос, однако, о SFINAE. Если предполагается, что SFINAE включится, то метод должен быть создан, а код и Clang верны; если СФИНАЕне Предполагается, что код введен, тогда код неправильный, а gcc верный. Я считаю, что Clang здесь верен, так как значения шаблона по умолчанию использовались для SFINAE в течение длительного времени.
 PiotrNycz10 окт. 2012 г., 10:48
gcc bugzilla полон ошибок SFINAE - это связано с вашей проблемой:gcc.gnu.org/bugzilla/show_bug.cgi?id=51047?
 SingerOfTheFall10 окт. 2012 г., 08:37
Ну это очевидноне иметьf, Является ли?
 BЈовић10 окт. 2012 г., 09:42
@MatthieuM. Метод шаблона не используется для объектаo2следовательно, это не должнобыть создан. Если он был использованo2 объект в конце, он должен нарушить компиляцию, потому чтоEmpty не имеет метода f. Это означает, что в этом случае Clang правильно, а GCC неправильно. Правильно ли мои рассуждения?
 Johannes Schaub - litb10 окт. 2012 г., 10:59
это не ошибка sfinae. sfinae не применяется, потому что T при создании экземпляра окружающего шаблона класса уже подставлен. Единственный вопрос - когда возникает серьезная ошибка, которая зависит от того, когда создается экземпляр аргумента по умолчанию для шаблона (я не знаю, что это не так).

Ответы на вопрос(1)

Решение Вопроса

14.6.3 [temp.nondep]:

1 - Независимые имена, используемые в определении шаблона, находятся с использованием обычного поиска имен и привязываются в той точке, в которой они используются.

В приведенном примере описывается, что неправильно сформированное выражение в определении шаблона "может быть диагностировано либо [в определении шаблона], либо в момент создания экземпляра ".

По умолчаниюШаблон-аргумент (14.1p9)U=decltype(t.f(1)) является независимым именем в контексте реализацииstruct outer (то есть, он не зависит от аргумента шаблона к своему собственному шаблону), поэтому он плохо сформирован для реализацииstruct outer сT = struct empty, Стандарт неt явно описывают, где оцениваются аргументы шаблона по умолчанию, но единственный разумный вывод заключается в том, что они обрабатываются как любая другая конструкция и оцениваются в точке, в которой они встречаются (или, в этом примере, в точке создания экземпляраstruct outer шаблон). Я неНе вижу никакой широты для компилятора, чтобы отложить оценку независимых аргументов шаблона по умолчанию в контекстах, где применяется SFINAE.

К счастью, решение простое: просто создайте шаблон по умолчаниюU зависимое имя:

    // if T have f(), define  outer_f()
    template<class t2="T," class="" u="decltype(static_cast<T2" &="">(t).f(1))> 
    int outer_f(int i) { return t.f(i); }
</class>
 Johannes Schaub - litb10 окт. 2012 г., 11:34
Жаль, что они не обрабатываются какаргументы по умолчанию, потому что аргументы по умолчанию обрабатываются как определения шаблонов с целью создания экземпляров. так что, если бы это был аргумент по умолчанию, он получил бы ошибку только при попытке использовать шаблон функции. но к сожалению то что у него есть по умолчаниюшаблон аргумент вместо.

Ваш ответ на вопрос