dan*_*ani 13 c++ variant c++17
我std::variant可以是空的(std::monostate),包含一个int,一个std::string或一个bool.
当我想用字符串提供它时,给定为var = "this is my string",它将转换为a bool而不是字符串.如果我明确声明类型,它可以工作var = std::string("this is my string").为什么会这样,我能做些什么来避免它?
#include <string>
#include <variant>
#include <iostream>
int main()
{
using var = std::variant<std::monostate, int, std::string, bool>;
var contains_nothing;
var contains_int = 5;
var contains_string = "hello";
var contains_expl_string = std::string("explicit hello");
var contains_bool = false;
auto visitor = [](auto&& arg){
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same<T, std::monostate>())
std::cout<<"nothing\n";
else if constexpr (std::is_same<T, int>())
std::cout<<"int: "<<arg<<"\n";
else if constexpr (std::is_same<T, std::string>())
std::cout<<"string: "<<arg<<"\n";
else if constexpr (std::is_same<T, bool>())
std::cout<<"bool: "<<arg<<"\n";
else
std::cout<<"Visitor is not exhaustive\n";
};
std::visit(visitor, contains_nothing); // nothing
std::visit(visitor, contains_int); // int: 5
std::visit(visitor, contains_string); // bool: 1
std::visit(visitor, contains_expl_string); // string: explicit hello
std::visit(visitor, contains_bool); // bool: 0
}
Run Code Online (Sandbox Code Playgroud)
编辑
由于我的代码的用户可能没有明确地编写string,我喜欢抓住它.否则它将成为错误的来源.我创建了模板辅助函数来检查是否char*已经传递了一个,如果是,则生成一个std :: string.效果很好.让这个更简单的帮助表示赞赏!
编辑2
通过声明std::monostate为默认参数/类型,它甚至可以在make_var没有任何参数的情况下调用.
#include <string>
#include <variant>
#include <iostream>
using var = std::variant<std::monostate, int, std::string, bool>;
template<typename T = std::monostate>
var make_var(T value = std::monostate())
{
if constexpr (std::is_same<typename std::remove_const<typename std::decay<T>::type>::type, const char*>())
return std::string(value);
return value;
}
int main()
{
auto contains_nothing = make_var();
auto contains_int = make_var(3);
auto contains_string = make_var("hello");
auto contains_expl_string = make_var(std::string("excplicit hello"));
var contains_bool = make_var(false);
auto visitor = [](auto&& arg){
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same<T, std::monostate>())
std::cout<<"nothing\n";
else if constexpr (std::is_same<T, int>())
std::cout<<"int: "<<arg<<"\n";
else if constexpr (std::is_same<T, std::string>())
std::cout<<"string: "<<arg<<"\n";
else if constexpr (std::is_same<T, bool>())
std::cout<<"bool: "<<arg<<"\n";
else
std::cout<<"Visitor is not exhaustive\n";
};
std::visit(visitor, contains_nothing);
std::visit(visitor, contains_int);
std::visit(visitor, contains_string);
std::visit(visitor, contains_expl_string);
std::visit(visitor, contains_bool);
}
Run Code Online (Sandbox Code Playgroud)
Rei*_*ica 28
的类型的"hello"是const char [6],它衰减到const char *.转换const char *为bool是内置转换,而转换const char *为std::string是用户定义的转换,这意味着执行前者.
由于您使用的是C++> = 14,因此可以使用文字后缀s来表示std::string文字:
using namespace std::string_literals;
var contains_string = "hello"s;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2089 次 |
| 最近记录: |