C++ 使用constexpr函数作为模板参数
我试图使用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 : _
#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());
}