标签: stdoptional

std :: optional <T>的开销?

既然已经接受了std :: experimental :: optional(或者即将被接受),我想知道当以下运算符获取内部值时,开销产生的开销和后果是什么:

->
*
value
value_or
Run Code Online (Sandbox Code Playgroud)

与没有的情况相比std::optional.对于计算密集型程序来说,这可能尤为重要.

例如,与a std::vector<std::experimental::optional<double>>相比,操作上的开销是std::vector<double>多少?

performance g++ overhead c++14 stdoptional

2
推荐指数
2
解决办法
2722
查看次数

clang6 实现 std::可选 吗?

我想使用 C++17std::optional但它似乎在 clang 中不存在:

> cat test.cxx 
#include <optional>

int main(int, char **) {
    return 0;
}
> $CXX --version | head -n1
clang version 6.0.0 (trunk 317775)
> $CXX -std=c++17 test.cxx 
test.cxx:1:10: fatal error: 'optional' file not found
#include <optional>
         ^~~~~~~~~~
1 error generated.
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我使用的是一个相当新版本的 clang,据我所知,clang 6 应该具有完整的 C++17 支持。乍一看,这似乎是一个 clang 问题,特别是因为包含<experimental/optional>工作正常,但也许是我遗漏了一些东西。你有什么想法?

谢谢

c++ clang stdoptional

2
推荐指数
1
解决办法
4494
查看次数

value_or的替代方法,对返回的类型无关紧要

我已经构建了一个Card重载<<运算符的小类,主要是打印出套装和卡的价值.

实现细节与我想问的问题无关,只是假设显而易见.因为Card我建了一堂课CardDeck.当然CardDeck可以用完卡片.这激发了我这种尝试:

std::optional<Card> CardDeck::drawCard() {
    if (this->Cards.empty()) {
        return std::nullopt;
    }
    else {
        Card card = this->Cards.front();
        this->Cards.pop_front();
        return std::optional<Card>{card};
    }
}
Run Code Online (Sandbox Code Playgroud)

现在可以绘制一张卡片并处理空牌组的可能性是客户端代码使用的责任CardDeck,但是这个方法并不总是返回一个值.我喜欢那个解决方案.

无论如何,C++的新手我做了天真的ansatz:

std::cout<< cardDeck.drawCard().value_or("Out of cards!");

这作为失败的类型,"Out of cards!"就是char*但不是Card.

我的问题:有没有办法保证优雅的oneliner没有检查和访问vaule /在两个单独的地方使用替换?

c++ stdoptional

2
推荐指数
1
解决办法
61
查看次数

为什么在访问空std :: optional时没有throw或sigsegv?

这个例子:

#include <optional>
#include <iostream>

using namespace std;

int main()
{
    optional<int> t{}; // nullopt (empty) by default

    cout << *t << endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

实际上这个程序打印一些int(未初始化的类型值int).此外,libcxx使用assert-check来访问非参与值.

为什么标准不要求扔或sigsegv在这里?

c++ segmentation-fault language-lawyer c++17 stdoptional

2
推荐指数
3
解决办法
183
查看次数

在这个简单示例中,为什么 std::optional 的赋值运算符在编译时上下文中不可用?

摆弄编译器资源管理器(以及在 std::optional 上阅读 cppref.com)半小时后,我放弃了。除了我不明白为什么这段代码不能编译之外,没有什么可说的。有人请解释这一点,如果有的话,也许可以告诉我一个解决方法?std::optional我在这里使用的所有成员函数都是constexpr,并且确实应该在编译时可计算,因为这里的可选类型 - size_t- 是原始标量类型。

#include <type_traits>
#include <optional>

template <typename T>
[[nodiscard]] constexpr std::optional<size_t> index_for_type() noexcept
{
    std::optional<size_t> index;
    if constexpr (std::is_same_v<T, int>)
        index = 1;
    else if constexpr (std::is_same_v<T, void>)
        index = 0;

    return index;
}
 
static_assert(index_for_type<int>().has_value());
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/YKh5qT4aP

c++ templates constexpr c++20 stdoptional

2
推荐指数
1
解决办法
76
查看次数

如何将字符串设置为可选字符串值?

由于程序(C++)中的某些限制,我遇到了将可选字符串分配给字符串变量的情况,这会出现以下错误:\nerror: no match for \xe2\x80\x98operator=\xe2\x80\x99 ...

\n

这段代码是这样的:

\n
void blah(std::experimental::optional<std::string> foo, // more parameters)\n{\n    std::string bar;\n    if(foo)\n    {\n        bar = foo; //error\n    }\n\n    // more code\n}\n
Run Code Online (Sandbox Code Playgroud)\n

尝试:

\n

我尝试使用以下方法将类型转换为匹配:

\n
bar = static_cast<std::string>(foo);\n
Run Code Online (Sandbox Code Playgroud)\n

最终显示此错误:

\n
error: no matching function for call to \xe2\x80\x98std::basic_string<char>::basic_string(std::experimental::optional<std::basic_string<char> >&)\xe2\x80\x99\n
Run Code Online (Sandbox Code Playgroud)\n

我想知道:

\n
    \n
  1. 有办法处理这种情况吗?
  2. \n
  3. 或者这是一个设计限制,我必须使用其他方法而不是将可选字符串分配给普通字符串?
  4. \n
\n

c++ string stdoptional

2
推荐指数
1
解决办法
2603
查看次数

返回 std::Optional&lt;T&gt; 而不复制

我目前正在学习 OpenGL,并在编写着色器抽象类时选择std::optional用于错误处理。现在为了防止意外的双重释放,我将删除复制构造函数

// Shader.h
Shader(const Shader&) = delete;
Shader& operator=(const Shader&) = delete;
Run Code Online (Sandbox Code Playgroud)

但回来时

// Shader.cpp
return std::make_optional<Shader>(Shader(id));
Run Code Online (Sandbox Code Playgroud)

在静态函数中fromSrc它给了我一个编译错误

Error (active)  E0304   no instance of overloaded function "std::make_optional" matches the argument list   LearnOpengl *\LearnOpengl\LearnOpengl\src\util\Shader.cpp   90  
Run Code Online (Sandbox Code Playgroud)

我正在使用 Visual Studio 2022 (MSVC v143) 和 c++17

编辑:我被告知要实现移动构造函数,这是一个很好的实现吗?

Error (active)  E0304   no instance of overloaded function "std::make_optional" matches the argument list   LearnOpengl *\LearnOpengl\LearnOpengl\src\util\Shader.cpp   90  
Run Code Online (Sandbox Code Playgroud)

c++ c++17 stdoptional

2
推荐指数
1
解决办法
444
查看次数

C++ 编译器提示“自动返回类型推导不一致”

C++ 中有一个很好的功能,您可以说该函数的返回类型为“auto”,编译器会计算出它。但是,如果我在错误时返回指针和 nullptr 该怎么办?不知何故,编译器无法推断出正确的类型并给出错误。

在下面的简单示例中,imaginestd::vector<int>计划在将来完全被其他东西取代,以证明此处使用 auto 的合理性:

#include<vector>
std::vector<int> e;
auto test(){
  if(!e.empty())
    return &e[0];
  return nullptr;
}
Run Code Online (Sandbox Code Playgroud)

在 c++17 中,我收到上述错误消息。

所以我尝试将最后一次返回替换为

return reinterpret_cast<decltype(&e[0])>(nullptr)

并得到错误invalid cast。我看到的唯一解决方案是将返回值替换为 3 行:

auto out=&e[0];
out=nullptr;
return out;
Run Code Online (Sandbox Code Playgroud)

我可能可以通过替换auto为某种 来将其减少到 2 行decltype,但我想其他类型的转换可以在一行中完成我想要的事情?或者我是否需要针对这种情况使用更新版本的 C++ 标准?

我还尝试了 std::make_Optional 并遇到了同样的问题,因为 nullopt_t 的类型与 std::Optional 不同。我真正喜欢的是,如果编译器能够自动推断类型无论如何std::optional......

c++ nullptr reinterpret-cast auto stdoptional

2
推荐指数
1
解决办法
438
查看次数

使用 std::Optional 使移动构造函数/分配中的 RAII 对象无效

假设我有一个 RAII 类,其实例永远不应该被复制:

class Session {

public:
    Session(); // Allocates a resource and sets generates a unique Session::id. 
    ~Session(); // Frees the resource

    Session(const Session&) = delete;
    Session& operator = (Session&) = delete;

private:
  std::uint32_t id;
}
Run Code Online (Sandbox Code Playgroud)

鉴于我不能允许复制,我想允许移动,所以我需要实现移动构造函数和移动赋值运算符,但我不确定应该如何处理Session::id移动的实例。

我可以:

  1. 将其设置为某个已知无效的值(可能将类型更改为有符号 int 并用作-1无效值)
  2. 使用类似的东西std::optional并将其设置为std::nullopt使其无效。

这些选项中哪一个(如果有的话)是正确的?

c++ raii c++20 stdoptional

2
推荐指数
1
解决办法
152
查看次数

为 std::可选对象的 std::array 赋值

我正在尝试填充 std::array 的 std::Optional 对象,如下所示。

\n
class MyClass\n{\n   private:\n    int distance;\n    MyClass(int x, int y);\n\n   friend class MasterClass;\n};\n\nMyClass::MyClass(int x, int y)\n{\n  distance = x+y;\n}\n\nclass MasterClass\n{\n  public:\n  MasterClass(std::array<std::optional<int>,5> xs, std::array<std::optional<int>,5> ys);\n  \n  private:\n  std::array<std::optional<MyClass>, 5> myclassarray{};\n\n};\n\nMasterClass::MasterClass(std::array<std::optional<int>,5> xs, std::array<std::optional<int>,5> ys)\n {\n     for(int i=0; i<5;i++)\n     {\n         myclassarray[i].emplace(new  MyClass(*xs[i], *ys[i])); //---(1)\n     }\n\n }\n
Run Code Online (Sandbox Code Playgroud)\n

从上面用 (1) 注释的行中,我收到以下错误,

\n
error: no matching function for call to std::optional<MyClass>::emplace(MyClass&)\n
Run Code Online (Sandbox Code Playgroud)\n

我也尝试用以下内容替换同一行

\n
 myclassarray[i] = new  MyClass(*xs[i], *ys[i]) ; //---(2)\n
Run Code Online (Sandbox Code Playgroud)\n

这会给我

\n
error: no match for \xe2\x80\x98operator=\xe2\x80\x99 …
Run Code Online (Sandbox Code Playgroud)

c++ stdarray c++17 stdoptional

1
推荐指数
1
解决办法
2082
查看次数