c++ - 如果变体之一没有特定字段,则无法访问该变体

标签 c++ c++17 std-variant

我正在尝试访问包含多个类的变体。其中一个没有特定的字段value,但我用constexpr处理它,但是编译器仍然无法编译。

#include <variant>
#include <iostream>

struct A {};

struct B {
    int value = 1;
};

struct C {
    int value = 2;
};

int main() {

    const auto d = std::variant<A, B, C>{B{}};
    auto n = std::visit(
        [&](auto &data) -> int {
            if constexpr (std::is_same_v<decltype(data), A>) {
                return int{0};
            } else {
                return data.value;
            }
        },
        d);
    std::cout << n << std::endl;
    return 0;
}

错误:

error: ‘const struct A’ has no member named ‘value’
   22 |                 return data.value;

编译器版本:

clang --version
clang version 10.0.0-4ubuntu1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

我错过了什么还是设计上不可能的?

编辑: 最短的解决方案是使用 std::decay_t ,但是,我不知道是否会产生任何后果:

if constexpr (std::is_same_v<std::decay_t<decltype(data)>, A>)

最佳答案

您需要删除数据的引用和cv限定符:

auto n = std::visit(
        [&](auto &data) -> int {
            if constexpr (std::is_same_v<std::remove_cvref_t<decltype(data)>, A>) {
                return int{0};
            } else {
                return data.value;
            }
        },
        d);

Demo

在 C++20 中,您可以仅使用 requires 子句来检测 data.value 表达式是否有效。

const auto d = std::variant<A, B, C>{B{}};
    auto n = std::visit(
        [&](auto& data) -> int {
            if constexpr (requires { data.value; }) {
                return data.value;
            } else {
                return int{0};
            }
        },
        d);

关于c++ - 如果变体之一没有特定字段,则无法访问该变体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70928527/

相关文章:

c++ - 在初始化列表中转换 shared_ptr

c++ - 有没有办法将 std::variant 与任意多个定义的类型一起使用?

c++ - 部分卡片上的 cuda 应用程序

c++ - 重载 ostream << 运算符

c++ - fopen 或 fstream 等是否会意外破坏文件 C/C++

c++ - 如何理解 foo(char (&p)[10]) ?

c++ - clang 左/右 3.6 倍表达式

c++ - MSVC : shift count negative or too big

c++ - 为什么不允许 std::variant 与其替代类型之一进行相等比较?

c++ - std::visit和std::variant用法