My std::variant
は空(std::monostate
)、int
、std::string
またはbool
を含むことができます。私のバリアントはstd :: stringをboolに変換するのはなぜですか?
var = "this is my string"
という文字列を入力すると、文字列ではなく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
}
EDIT 私のコードのユーザーが明示的にstring
秒をしないかもしれないので、私はそれをキャッチしたいです。それ以外の場合は、エラーの原因になります。 char*
が渡されたかどうかを確認するテンプレートヘルパー関数を作成し、そうであればstd :: stringを作成します。うまくいく。これを簡単にするためのヘルプは高く評価されています!
EDIT 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);
}
'のstd ::に好まれるSTRING'べき理由聞いてもう一つの問題は、あります'ブール'?どちらも配列の減衰と型変換が必要です。 – juanchopanza
テンプレートを使用した特に私の回避策;-)を使用して、私の素敵な答えをhttp://stackoverflow.com/questions/44021989/implicit-cast-from-const-string-to-boolで見ることができます。しかし、ユーザー定義のリテラル(以下)のAngewの使用はより控えめです。 – Bathsheba
短い答え:それはあなたが与えた 'std :: string'ではないので、そうではありません。 –