Информация об изменениях

Сообщение Re: Почему clang не компилирует этот код в отличии от gcc от 18.03.2023 18:30

Изменено 18.03.2023 18:31 rg45

Re: Почему clang не компилирует этот код в отличии от gcc
Здравствуйте, niralex, Вы писали:


N>Компилятор clang выдает маловразумительные сообщения:

N>main.cpp|18|error: no matching function for call to 'Test'|
N>main.cpp|7|note: candidate template ignored: invalid explicitly-specified argument for template parameter 'ptr'|
N>Как можно минимально поправить код, чтобы и clang и gcc компилировали?

На самом деле, этот пример и gcc компилирует только на 20-м стандарте. Если снизиться до C++17:

http://coliru.stacked-crooked.com/a/3feedc4e7b04aa3f

#include <iostream>
#include <array>

using namespace std;

template<const int * ptr>
constexpr const int *Test()
{
    return ptr + 1;
}

constexpr array<int, 3> ar{1, 2, 3};

int main()
{
    constexpr auto x = Test<ar.data()>(); // 1

    cout << *x << endl;
}


то компилер выдает достаточно информативное сообщение:

main.cpp:16:39: error: '& ar.std::array<int, 3>::_M_elems' is not a valid template argument of type 'const int*' because 'ar.std::array<int, 3>::_M_elems' is not a variable
   16 |     constexpr auto x = Test<ar.data()>(); // 1


То есть, попросту говоря, массив, инкапсулированный внутри std::array, не является объектом с внешним связывание и поэтому не годится в качестве аргумента шаблона.
Re: Почему clang не компилирует этот код в отличии от gcc
Здравствуйте, niralex, Вы писали:


N>Компилятор clang выдает маловразумительные сообщения:

N>main.cpp|18|error: no matching function for call to 'Test'|
N>main.cpp|7|note: candidate template ignored: invalid explicitly-specified argument for template parameter 'ptr'|
N>Как можно минимально поправить код, чтобы и clang и gcc компилировали?

На самом деле, этот пример и gcc компилирует только на 20-м стандарте. Если снизиться до C++17:

http://coliru.stacked-crooked.com/a/3feedc4e7b04aa3f

#include <iostream>
#include <array>

using namespace std;

template<const int * ptr>
constexpr const int *Test()
{
    return ptr + 1;
}

constexpr array<int, 3> ar{1, 2, 3};

int main()
{
    constexpr auto x = Test<ar.data()>(); // 1

    cout << *x << endl;
}


то компилер выдает достаточно информативное сообщение:

main.cpp:16:39: error: '& ar.std::array<int, 3>::_M_elems' is not a valid template argument of type 'const int*' because 'ar.std::array<int, 3>::_M_elems' is not a variable
   16 |     constexpr auto x = Test<ar.data()>(); // 1


То есть, попросту говоря, массив, инкапсулированный внутри std::array, не является объектом с внешним связывание и поэтому не годится в качестве аргумента шаблона. Вполне вероятно, в clang та же проблема.