我有一个包含两个键入值的表。在生产代码中,我在元组中搜索给定值。我没有得到的是,如果在元组中找不到该值,我想得到一个编译时错误。下面的例子:
我有这个功能:
template <typename TLookup, typename TValueToSearch, typename TSetting>
constexpr auto lookupNeededSetting(const TValueToSearch &valueToSearch)
{
TSetting setting = {};
typename TLookup::Type const table = typename TLookup::Type{};
std::apply(
[&valueToSearch, &setting](const auto &...entry) {
// Iterate over each entry in the table
return (((entry.fits(valueToSearch)) ? setting = entry.value() : false) || ...);
},
table);
return setting;
}
这会像这样搜索给定的表:
template <typename... TEntries>
struct LookupTable
{
using Type = std::tuple<TEntries...>; ///< Type representing the tuple of entries.
};
给定的条目有一个函数
fits
,它检查给定的值是否相同,如果是,则返回翻译后的值。不起作用的是,如果给定的值不在表中,我希望出现编译时错误,但我无法让它工作。这可能吗?
它的用法是这样的:
using TestValueLookup = LookupTable<Entry<TypedValue<uint16_t, 1>, TypedValue<uint8_t, 0x00>>,
Entry<TypedValue<uint16_t, 2>, TypedValue<uint8_t, 0x01>>,
Entry<TypedValue<uint16_t, 3>, TypedValue<uint8_t, 0x02>>,
Entry<TypedValue<uint16_t, 4>, TypedValue<uint8_t, 0x03>>>;
constexpr auto settingValue = utilities::lookupNeededSetting<TestValueLookup, uint16_t, uint8_t>(1);
新示例:
template <typename TLookup, typename TValueToSearch, typename TSetting, auto VValueToSearch>
constexpr bool lookupNeededSetting2(TSetting& setting) {
bool found = false;
typename TLookup::Type const table = typename TLookup::Type{};
std::apply(
[&found, &setting](const auto&... entry) {
// Iterate over each entry in the table
((entry.fits(VValueToSearch) ? (setting = entry.value(), found = true) : false) || ...);
},
table);
return found;
}
template <typename TLookup, typename TValueToSearch, typename TSetting, auto VValueToSearch>
class Lookup {
public:
static constexpr TSetting setting = [] {
TSetting tempSetting{};
constexpr bool found = lookupNeededSetting2<TLookup, TValueToSearch, TSetting, VValueToSearch>(tempSetting);
static_assert(found, "The given VValueToSearch was not found in the lookup table.");
return tempSetting;
}();
static constexpr auto value = setting;
};
不幸的是编译器抱怨 tempSetting 它不是常量
我现在的解决方案是这样的:
template <typename TSetting>
class Setting
{
public:
bool m_found = false;
TSetting m_value;
};
template <typename TLookup, typename TValueToSearch, typename TSetting, auto VValueToSearch>
constexpr Setting<TSetting> lookupNeededSetting2()
{
Setting<TSetting> setting{};
typename TLookup::Type const table = typename TLookup::Type{};
std::apply(
[&setting](const auto &...entry) {
// Iterate over each entry in the table
((entry.fits(VValueToSearch) ? (setting.m_value = entry.value(), setting.m_found = true) : false) || ...);
},
table);
return setting;
}
template <typename TLookup, typename TValueToSearch, typename TSetting, auto VValueToSearch>
class Lookup
{
public:
static constexpr auto getSetting = [] {
return lookupNeededSetting2<TLookup, TValueToSearch, TSetting, VValueToSearch>();
}();
static constexpr auto setting = getSetting;
static_assert(setting.m_found, "Your searched setting was not found.");
};