使用constexpr函数作为模板参数

时间:2018-05-17 12:21:49

标签: c++ c++17

我正在尝试使用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());

我试图不将参数赋给operator()一个引用,但这只会添加更多警告消息。我不能使_data成员成为constexpr,因为这是不允许的。

我会使用以下代码:

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

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

这意味着存储系统可以轻松创建不同的分区(或存储桶)。

1 个答案:

答案 0 :(得分:3)

您的代码无法编译,因为在:

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会有什么意义?< / p>