Передать ссылку на статический массив стилей хранения из функции constexpr в другую функцию constexpr - PullRequest
0 голосов
/ 29 января 2019

Я не могу передать глобальный массив стиля в функцию constexpr для C ++ 14.У меня есть такой массив:

static const char t[] = "sometext";

И у меня есть две функции:

template <typename T, typename U, std::size_t N>
constexpr static auto count(T (&arr)[N], const U &val)
{
    auto cnt = 0;
    auto it(std::cbegin(arr));
    while (it != std::cend(arr))
    {
        if (*it == val)
            cnt++;
        it++;
    }
    return cnt;
}

template <typename T, std::size_t N> constexpr static auto count_wrapper(T (&arr)[N])
{
    constexpr auto num_elems(count(arr, ','));
    return num_elems;
}

Когда я вызываю первую функцию, как это:

std::cout << count(t, ',') << std::endl;

Iможет скомпилировать код и запустить его, но когда я вызываю вторую функцию следующим образом:

count_wrapper(t);

я получаю сообщение об ошибке:

main.cpp: в экземпляре 'constexprauto t (T (&) [N]) [с T = const char;long unsigned int N = 46] ': main.cpp: 51: 53: необходимо отсюда main.cpp: 40: 35: в constexpr расширение' count ((* & arr), ',') 'main.cpp:40:20: ошибка: 'arr' не является константным выражением constexpr auto num_elems (count (arr, ',') + 1);

1 Ответ

0 голосов
/ 29 января 2019

Аргументы не являются / не могут быть constexpr.(constexpr функции могут использоваться в контексте non-constexpr).

Обратите внимание, что std::cout << count(t, ',') << std::endl; может быть вычислено во время выполнения.вам потребуется

constexpr auto c = count(t, ',');
std::cout << c << std::endl;

, чтобы получить constexpr оценочную гарантию.

При необходимости вы можете заключить значение в тип.

template <typename T, T ... cs, typename U>
constexpr static auto count(std::integer_sequence<T, cs...>, const U &val)
{
    const T arr[] = {cs...};
    auto cnt = 0;
    auto it(std::cbegin(arr));
    while (it != std::cend(arr))
    {
        if (*it == val)
            cnt++;
        it++;
    }
    return cnt;
}

auto sometext = std::integer_sequence<char,
                                      's', 'o', 'm', 'e', 't', 'e', 'x', 't' /*, '\0'*/>;

constexpr auto num_elems(count(sometext, ','));
...