У меня в основном есть класс, который зависит от параметра шаблона, отличного от типа. Я определил кастинг таким образом, чтобы объект шаблона N
мог преобразовать в другой из M
У меня есть минимальный пример, который может воспроизвести ситуацию:
template<auto Integral>
class Test{
public:
typedef decltype(Integral) value_type;
static constexpr value_type N = Integral;
constexpr Test (const value_type& x = 0);
template<auto Integral2>
constexpr explicit operator Test<Integral2>() const;
private:
value_type n;
};
template<auto Integral>
constexpr Test<Integral>::Test (const value_type& x){
if (x < 0){
n = N - (-x)%N;
}
else{
n = x%N;
}
}
template<auto Integral> template<auto Integral2>
constexpr Test<Integral>::operator Test<Integral2>() const{
return Test<Integral2>(n%(Test<Integral2>::N));
}
Я компилирую GCC 7.2.0 и Clang 5.0.0 в Ubuntu 16.04 LTS с флагами -O2 -std=c++17
.
Проблема в том, что я все время скомпилировал с помощью g++, и все работало, как ожидалось, но затем я попробовал clan g++, чтобы проверить, все ли еще компилируется.
К моему удивлению, это было не так, поскольку клан g++ жаловался на некоторые части, которые g++ этого не делал. Вы можете проверить представление diff в Compiler Explorer.
Одним из сообщений об ошибках, которые создает клан g++, является:
error: out-of-line definition of 'operator Test<Integral2>' does not match any declaration in 'Test<Integral>'
Это заставляет меня думать, что клан g++ не нашел "правильной" декларации о конверсии, но я не знаю.
Примечание. Эта первая ошибка появляется только при отмене объявления из определения. В противном случае это кажется правильным.
Это вторая ошибка, создаваемая кланом g++:
error: a non-type template parameter cannot have type 'auto'
Но это меня еще больше удивляет, потому что ошибка говорит о том, что должно быть допустимо в С++ 17. Наверное, мне что-то не хватает, потому что это просто не имеет смысла для меня.
Имейте в виду, что эта вторая ошибка появляется только в случае этого преобразования. В любом месте в фактическом коде появляется ошибка (хотя есть еще много параметров шаблона auto
не-типа).
На данный момент у меня есть некоторые вопросы:
- Что вызывает ошибку в случае компилятора clang?
- Какой из них правильный, в соответствии со стандартом?