我正在尝试将 C++17 中的 constexpr 构造函数与 lambda 一起使用,该 lambda 使用
std::tie
从元组初始化类中的字段。
代码类似这样:
#include <tuple>
enum class Format {
UINT8,
UINT16
};
struct FormatInfo {
const char* name = nullptr;
int maxVal = 0;
constexpr explicit FormatInfo(Format fmt) {
auto set = [this](const auto&... args) constexpr {
std::tie(name, maxVal) = std::make_tuple(args...);
};
switch(fmt) {
case Format::UINT8: set("uint8", 255); break;
case Format::UINT16: set("uint16", 65535); break;
}
}
};
int main() {
FormatInfo info(Format::UINT8); // ok
constexpr FormatInfo info2(Format::UINT8); // fails
}
将构造函数作为 constexpr 调用失败,并出现错误,指出在
set
内部调用了非 constexpr 函数。即使 std::tie
和 std::make_tuple
都应该是 constexpr。
使 lambda 本身为 constexpr (
constexpr auto set = ...
) 也会失败,并出现错误:this
不是常量表达式。
有什么办法可以让这个在 C++17 中工作吗?
std::tie
返回引用类型的元组。在 C++17 中,std::tuple<...>::operator=
未标记为 constexpr
。
您可以用其他 (
operator=
) 函数来模拟 constexpr
的作用:
auto set = [this](const auto&... args) {
std::apply([&](auto&... tied) {
(void(tied = args), ...);
}, std::tie(name, maxVal));
// std::tie(name, maxVal) = std::make_tuple(args...);
};
或者你可以放弃元组:
auto set = [this](const auto& name, const auto& maxVal) {
this->name = name;
this->maxVal = maxVal;
};