Ответ 1
Расхождение между компиляторами обусловлено определением void_t
:
Есть ли ошибка компилятора, представленная моей реализацией свойства типа is_complete?
Короче говоря, в стандарте неясно, могут ли неиспользуемые аргументы в специализированных шаблонах псевдонимов привести к смене замены или просто игнорируются. Резолюция CWG issue 1558 поясняет, что более короткое определение void_t
в вопросе должно работать.
С этой проблемой работала с использованием
template<typename... Ts>
struct make_void { typedef void type;};
template<typename... Ts>
using void_t = typename make_void<Ts...>::type;
оба компилятора производят 10
.
§14.6.4.2 [temp.dep.candidate]:
Для вызова функции, который зависит от параметра шаблона, функции-кандидата найдены с использованием обычных правил поиска (3.4.1, 3.4.2, 3.4.3), за исключением того, что:
- Для части поиска, использующей поиск неквалифицированного имени (3.4.1) или поиск по квалифицированному имени (3.4.3), только объявления функций из контекст определения шаблона.
- Для части поиска с использованием связанных пространств имен (3.4.2) только объявления функций, найденные в контексте определения шаблона или контекст экземпляра шаблона.
Если имя функции является неквалифицированным идентификатором, и вызов будет плохо сформировался или нашел бы лучшее совпадение, если бы поиск в пределах связанные пространства имен считаются всеми объявлениями функций с внешняя связь, введенная в эти пространства имен во всем переводе единиц, а не только с учетом тех объявлений, которые указаны в шаблоне контекста определения контекста и шаблона, то программа undefined.
Неквалифицированный поиск Serialize
выполняется в контексте определения шаблона и не находит Serialize(int &)
, и нет ADL для аргумента типа int&
, поэтому 10
является правильным выходом.