I'm trying to use a constexpr constructor in C++17 with a lambda that uses std::tie to initialize fields in a class from a tuple.
The code is similar to this:
#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
}
Calling the constructor as constexpr fails, with an error that there is a call to a non-constexpr function inside set. Even though both std::tie and std::make_tuple should be constexpr.
Making the lambda itself constexpr (constexpr auto set = ...) also fails with an error that this is not a constant expression.
Is there any way to make this work in C++17?
std::tiereturns a tuple of reference types.std::tuple<...>::operator=is not markedconstexprin C++17.You can emulate what
operator=does with other (constexpr) functions:Or you can ditch the tuples: