Использование функции constexpr в качестве параметра шаблона - PullRequest
0 голосов
/ 17 мая 2018

Я пытаюсь использовать результат функции constexpr в качестве параметра шаблона и не могу понять, как заставить его работать. У меня есть следующий код:

#include <functional>
#include <string_view>

class slice
{
    public:
        template <std::size_t size>
        constexpr slice(char const (&data)[size]) noexcept :
            _size(size),
            _data(data)
        {}

        constexpr const char *data() const
        {
            return _data;
        }

        constexpr std::size_t size() const
        {
            return _size;
        }
    private:
        const size_t    _size;
        const char      *_data;
};

template <std::size_t size>
class key
{
    public:
        constexpr key(std::size_t hash, const char *data) :
            _hash(hash),
            _data(data, data + size)
        {}
    private:
        std::size_t             _hash;
        std::array<char, size>  _data;
};

class partition
{
    public:
        partition(std::string_view name) :
            _hash(std::hash<std::string_view>{}(name))
        {}

        auto operator()(const slice &data)
        {
            return key<data.size()>(_hash, data.data());
        }
    private:
        const std::size_t   _hash;
};

Даже не пытаясь использовать эти классы, он отказывается компилировать. Я получаю следующую ошибку:

ошибка: нетипизированный аргумент шаблона не является константным выражением

       return key<data.size()>(_hash, data.data());

Я пытался не делать параметр для оператора () ссылкой, но это только добавляет больше предупреждающих сообщений. Я не могу сделать член _data constexpr, потому что это недопустимо.

Я бы использовал этот код примерно так:

partition partition1{ "partition 1" };
partition partition2{ "partition 2" };

auto key1 = partition1("key 1");
auto key2 = partition2("key 1");

Он предназначен для того, чтобы система хранения могла легко создавать различные разделы (или сегменты).

1 Ответ

0 голосов
/ 17 мая 2018

Ваш код не может быть скомпилирован, потому что в:

constexpr auto operator()(const slice &data)
{
    return key<data.size()>(_hash, data.data());
}

... data не гарантируется равным constexpr. Вы можете использовать параметр шаблона:

template <const slice& data>
constexpr auto operator()()
{
    return key<data.size()>(_hash, data.data());
}

... но тогда какой смысл делать это constexpr, если вы не можете создать экземпляр constexpr partition из-за не constexpr конструктора?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...