Определение функции вне универсального класса приводит к ошибке компиляции

#c #templates #default-arguments

#c #шаблоны #по умолчанию -аргументы

Вопрос:

Контекст

Я написал следующий минимальный рабочий пример

 #include <iostream>

template <typename T>
struct A {
  enum myenum {faa, fee, fii};
  myenum m_m;
  A(const myenumamp; m = faa): m_m(m) {}
};

int main() {
  A<int> a1;
  A<int> a2(A<int>::fii);

  std::cout << a1.m_m << std::endl
            << a2.m_m << std::endl;
  return 0;
}
  

Его компиляция и выполнение приводят к

 $ g   main.cpp amp;amp; ./a.out
0
2
  

Проблема

Однако, когда определение функции записывается вне класса (то есть, как показано ниже)

 #include <iostream>

template <typename T>
struct A {
  enum myenum {faa, fee, fii};
  myenum m_m;
  A(const myenumamp; m);
};

template <typename T>
A<T>::A(const myenumamp; m = A<T>::faa): m_m(m) {}

int main() {
  A<int> a2(A<int>::fii);

  std::cout << a2.m_m << std::endl;
  return 0;
}
  

Я получаю следующую ошибку компиляции

 $ g   main.cpp amp;amp; ./a.out
main.cpp:11:1: error: redeclaration of ‘A<T>::A(const A<T>::myenumamp;)’ may not have default arguments [-fpermissive]
   11 | A<T>::A(const myenumamp; m = A<T>::faa): m_m(m) {}
      | ^~~~
  

Вопрос

Как я могу избавиться от этой ошибки компиляции?

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

1. Прочитайте сообщение об ошибке и избавьтесь от аргументов по умолчанию в определении.

Ответ №1:

Вы должны указать аргумент по умолчанию в объявлении и удалить его из определения.

Для функций-членов шаблонов классов все значения по умолчанию должны быть указаны в первоначальном объявлении функции-члена.

 template <typename T>
struct A {
  enum myenum {faa, fee, fii};
  myenum m_m;
  A(const myenumamp; m = faa);
};

template <typename T>
A<T>::A(const myenumamp; m): m_m(m) {}