既然已经接受了std :: experimental :: optional(或者即将被接受),我想知道当以下运算符获取内部值时,开销产生的开销和后果是什么:
->
*
value
value_or
Run Code Online (Sandbox Code Playgroud)
与没有的情况相比std::optional.对于计算密集型程序来说,这可能尤为重要.
例如,与a std::vector<std::experimental::optional<double>>相比,操作上的开销是std::vector<double>多少?
我想使用 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>工作正常,但也许是我遗漏了一些东西。你有什么想法?
谢谢
我已经构建了一个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 /在两个单独的地方使用替换?
这个例子:
#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在这里?
摆弄编译器资源管理器(以及在 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)
由于程序(C++)中的某些限制,我遇到了将可选字符串分配给字符串变量的情况,这会出现以下错误:\nerror: no match for \xe2\x80\x98operator=\xe2\x80\x99 ...
这段代码是这样的:
\nvoid 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}\nRun Code Online (Sandbox Code Playgroud)\n尝试:
\n我尝试使用以下方法将类型转换为匹配:
\nbar = static_cast<std::string>(foo);\nRun Code Online (Sandbox Code Playgroud)\n最终显示此错误:
\nerror: no matching function for call to \xe2\x80\x98std::basic_string<char>::basic_string(std::experimental::optional<std::basic_string<char> >&)\xe2\x80\x99\nRun Code Online (Sandbox Code Playgroud)\n我想知道:
\n我目前正在学习 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++ 中有一个很好的功能,您可以说该函数的返回类型为“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......
假设我有一个 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无效值)std::optional并将其设置为std::nullopt使其无效。这些选项中哪一个(如果有的话)是正确的?
我正在尝试填充 std::array 的 std::Optional 对象,如下所示。
\nclass 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 }\nRun Code Online (Sandbox Code Playgroud)\n从上面用 (1) 注释的行中,我收到以下错误,
\nerror: no matching function for call to std::optional<MyClass>::emplace(MyClass&)\nRun Code Online (Sandbox Code Playgroud)\n我也尝试用以下内容替换同一行
\n myclassarray[i] = new MyClass(*xs[i], *ys[i]) ; //---(2)\nRun Code Online (Sandbox Code Playgroud)\n这会给我
\nerror: no match for \xe2\x80\x98operator=\xe2\x80\x99 …Run Code Online (Sandbox Code Playgroud)