【发布时间】:2023-03-16 02:25:01
【问题描述】:
我正在尝试将 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");
这意味着存储系统能够轻松创建不同的分区(或存储桶)。
【问题讨论】:
-
如果你不能拥有
partitionconstexpr的构造函数,那么拥有operator()constexpr的目的是什么? -
@Holt:我不太明白你的意思。这个想法是 operator() 可以使用正确的模板参数自动创建一个键实例。分区构造函数不是 constexpr 完全无关紧要。
-
为了在
partition的实例上调用operator(),您需要首先创建partition的实例。如果您没有constexpr构造函数,您将永远无法创建constexpr partition,因此您将永远无法在constexpr上调用operator(),因此constexpr限定符是无用的。 -
好的,我将从 operator() 中删除 constexpr 限定符。不过,这并没有改变原来的问题:如何让 operator() 选择正确的模板参数来构造键。
-
看我的回答。如果您想了解更多详细信息,则需要在实际调用此运算符的位置提供示例代码。