C++ 使用constexpr函数作为模板参数

C++ 使用constexpr函数作为模板参数,c++,c++17,C++,C++17,我试图使用constexpr函数的结果作为模板参数,但无法确定如何使其工作。我有以下代码: #include <functional> #include <string_view> class slice { public: template <std::size_t size> constexpr slice(char const (&data)[size]) noexcept : _

我试图使用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;
};

这意味着存储系统能够轻松创建不同的分区或存储桶。

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

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

…但是,如果由于非constexpr构造函数而无法实例化constexpr分区,那么创建此constexpr有什么意义呢?

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

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

…但是,如果由于非constexpr构造函数而无法实例化constexpr分区,那么制作这个constexpr有什么意义呢?

如果无法拥有分区constexpr的构造函数,那么使用操作符constexpr有什么意义?@Holt:我真的不理解你的观点。其思想是,操作员可以使用正确的模板参数自动创建一个关键实例。分区构造函数不是constexpr是完全不相关的。为了调用分区实例上的运算符,您需要首先创建一个分区实例。如果没有constexpr构造函数,则永远无法创建constexpr分区,因此永远无法对constexpr调用运算符,因此constexpr限定符无效。好的,我将从运算符中删除constexpr限定符。但这并没有改变原来的问题:如何让操作员为构造密钥选择正确的模板参数。请参阅我的答案。如果你想要更多的细节,你需要在你实际调用这个操作符的地方编写一个示例代码。如果你不能拥有分区constexpr的构造函数,那么拥有操作符constexpr的目的是什么?@Holt:我真的不明白你的意思。其思想是,操作员可以使用正确的模板参数自动创建一个关键实例。分区构造函数不是constexpr是完全不相关的。为了调用分区实例上的运算符,您需要首先创建一个分区实例。如果没有constexpr构造函数,则永远无法创建constexpr分区,因此永远无法对constexpr调用运算符,因此constexpr限定符无效。好的,我将从运算符中删除constexpr限定符。但这并没有改变原来的问题:如何让操作员为构造密钥选择正确的模板参数。请参阅我的答案。如果你想要更多的细节,你需要在你实际调用这个操作符的地方编写一个示例代码。这当然不行。模板参数不能是类实例。@MartijnOtto如果数据是constexpr,则此操作有效,但当然它不适用于非constexpr数据。如果数据不是constexpr,则无法在编译时访问data.size,因此不能将data.size用作模板参数。@ildjarn否,它不是。您可以使用左值引用作为模板参数。参见例如,或。当然,您不能像这样调用它并期望编译器从const char[]创建一个const slice,但这是另一回事。我的编译器clang 3.8.0不接受它:错误:二进制表达式“partition”和“slice”的操作数无效,是的,当然是常量数据。@MartijnOtto工作得很好,错误与此无关。const不是constexpr,您需要一个静态片才能工作。当然,这在你的情况下不起作用,但在你发布实际使用之前,我猜不到。这当然不起作用。模板参数不能是类实例。@MartijnOtto如果数据是constexpr,则此操作有效,但当然它不适用于非constexpr数据。如果数据不是constexpr,则无法在编译时访问data.size,因此不能将data.size用作模板参数。@ildjarn否,它不是。您可以使用左值引用作为模板参数。参见例如,或。当然,您不能像这样调用它并期望编译器从const char[]创建一个const slice,但这是另一回事。我的编译器clang 3.8.0不接受它:错误:二进制表达式“partition”和“slice”的操作数无效,是的,当然是常量数据。@MartijnOtto工作得很好,错误与此无关。const不是constexpr,您需要一个静态片才能工作。当然,这在您的情况下不起作用,但在您发布实际使用之前,我无法猜到它。
constexpr auto operator()(const slice &data)
{
    return key<data.size()>(_hash, data.data());
}
template <const slice& data>
constexpr auto operator()()
{
    return key<data.size()>(_hash, data.data());
}