【问题标题】:Why does std::variant behave differently on GCC 8.5 and GCC 12.1 in respect to a `const char *` literal? [duplicate]为什么 std::variant 在 GCC 8.5 和 GCC 12.1 上的 `const char *` 文字表现不同? [复制]
【发布时间】:2022-08-10 03:25:50
【问题描述】:
#include <iostream>
#include <string>
#include <variant>

int main()
{
    std::variant<std::string, bool> v{ \"hasta la vista\" };
    std::cout << std::boolalpha << std::holds_alternative<std::string>(v) << \' \' << std::holds_alternative<bool>(v) << std::endl;
}

GCC 12.1.1

$ g++ std_alternative.cpp 
$ ./a.out 
true false

海合会 8.5.0

$ g++ -std=c++17 std_alternative.cpp 
$ ./a.out 
false true

为什么输出不一样?根据 c++17 哪个是正确的?我应该怎么做才能使我的代码以相同的方式在两个版本的 GCC 上工作?

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


【解决方案1】:
struct explicit_bool {
  bool b = false;
  template<class T,
   std::enable_if_t<std::is_same_v<T, bool>, bool> = true
  >
  explicit_bool( T v ):b(v){}
  explicit_bool(explicit_bool const&) noexcept=default;
  explicit_bool& operator=(explicit_bool const&)& noexcept=default;
  explicit_bool()noexcept=default;
  ~explicit_bool()noexcept=default;
  bool operator!() const { return !b; }
  explicit operator bool() const { return b; }
};

存储其中一个(而不是bool)。

它只接受实际的bools 和其他explicit_bools 作为参数。

执行此操作后,您可能需要在代码中添加一些显式转换 to-from bool。您可能会感兴趣的是,(bool) 作为演员表总是做与static_cast&lt;bool&gt; 完全相同的事情,这与许多其他 C 风格演员表相比,与 C++ 风格演员表不同;这可以减轻痛苦。另一个选择是!!,它将大多数类型隐式转换为bool

【讨论】:

    【解决方案2】:

    为了解决 GCC 8.5 上的问题,我将变体更改为

    std::variant<std::string, const char *, bool> v{ "hasta la vista" };
    

    这给了我在 GCC 12 和 GCC 8 上的const char *。看起来const char * 胜过bool

    在随后的代码中,我将处理提供字符串的两种方式。 IMO 比保持变体不变并要求用户通过 std::string("hasta la vista") 或处理 ""s 后缀魔术要好。要么很容易忘记,然后我又遇到麻烦了!

    想不出更好的办法。

    【讨论】:

    • 请注意原始指针不拥有它们的目标。在您的变体中保存的const char* 可能会在您想要它之前悬空。
    猜你喜欢
    • 1970-01-01
    • 2013-05-17
    • 2017-03-18
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-15
    相关资源
    最近更新 更多