在 constexpr 构造函数中使用 lambda 函数和 std::tie

问题描述 投票:0回答:1

我正在尝试将 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 中工作吗?

c++ lambda c++17 constexpr stdtuple
1个回答
0
投票

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;
};
© www.soinside.com 2019 - 2024. All rights reserved.