Могут ли специальные функции-члены выполняться по умолчанию, если они используют typedefs?

#c #language-lawyer #defaulted-functions

#c #язык-юрист #default-функции

Вопрос:

Clang компилирует это нормально, но GCC и MSVC жалуются, что operator= это не может быть выполнено по умолчанию:

 #include <type_traits>

template<class T>
struct S
{
    typedef typename std::enable_if<!std::is_enum<T>::value, S>::type Me;
    S amp;operator=(Me const amp;) = default;
};

int main()
{
    S<int> s1, s2;
    s1 = s2;
}
 

Является ли этот код законным? Если нет, было бы законно, если Me бы было определено как typedef S Me; ?

Комментарии:

1. AFAIK, это незаконно (или, по крайней мере, не имеет смысла) использовать std::enable_if в typedef подобном случае. Он предназначен для использования либо в параметре шаблона, либо в параметре функции, либо в возвращаемом значении функции, а не для определения псевдонимов типов. Вы пытаетесь определить оператор присваивания копирования, поэтому входной параметр должен быть S const amp; безоговорочным.

2. Более простой пример: все компиляторы успешно работают для using Me = S<T>; , но GCC и MSVC терпят неудачу для using Me = std::type_identity_t<S<T>>;

3. @Kevin using более мощный, чем typedef , так что это не сравнение яблок с яблоками. using более мощный, особенно в отношении шаблонов.

4. @sweenish: using полностью эквивалентно typedef (за исключением синтаксиса), за исключением того, что ему может предшествовать непосредственно template<…> .

5. @sweenish Нам не нужно вводить шаблон здесь

Ответ №1:

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

Как кто-то указал выше, похоже, что отчет об ошибке отслеживает эту проблему.