我有一个增强::不同类型的变体,其中一个是(const)空指针,另一个是字符串。
boost::variant<std::string, void const*>;
问题是,如果我想将它与c-字符串一起使用,它将它转换为空指针而不是字符串。
boost::variant<std::string, void const*> foo;
foo = "bar";
std::cout << foo.which(); // prints 1 -> void const*
如果我移除指针的恒定性,它将把它转换成字符串。
boost::variant<std::string, void*> foo; // no const pointer
foo = "bar";
std::cout << foo.which(); // prints 0 -> string
有没有一种简单的方法可以使boost::variant隐式地将c-字符串强制转换为std::string?
更新
我知道我可以用以下几个字来表达:
foo = std::string("bar");
但我想避免明显的演员阵容。
发布于 2015-06-23 09:05:59
您可以通过从boost::variant
继承来提供自己的变体模板。从const char*
到std::string
的正确转换是通过重载operator=
实现的
#include <iostream>
#include <string>
#include <boost/variant.hpp>
template <typename... Types>
struct my_variant : public boost::variant<Types...>
{
using boost::variant<Types...>::variant;
auto operator=(const char* rhs)
{
return boost::variant<Types...>::operator=(std::string(rhs));
}
};
int main()
{
my_variant<std::string, void const*> foo;
foo = "bar";
std::cout << foo.which();
return 0;
}
按需要输出"0“。
通过使用一个特性类(它指定类型映射),这一想法甚至可以得到更广泛的推广:
template <template <typename> class conv_traits, typename... Types>
struct my_variant : public boost::variant<Types...>
{
using boost::variant<Types...>::variant;
template <typename T>
auto operator=(T rhs)
{
return boost::variant<Types...>::operator=(static_cast<typename conv_traits<T>::type>(rhs));
}
};
template <typename T>
struct conversion_traits
{
typedef T type;
};
template <>
struct conversion_traits<const char*>
{
typedef std::string type;
};
my_variant<conversion_traits, std::string, void const*> foo;
发布于 2015-06-23 08:55:43
据我所知,没有办法直接解决这个问题,但是你可以用包装器来解决这个问题。基本元素(按您的需要进行修饰,并根据您的需要进行概括):
struct VariantWrapper
{
template <class T>
VariantWrapper& operator=(const T& val)
{
var = val;
return *this;
}
template <int N>
VariantWrapper& operator=(const char(&str)[N])
{
var = std::string(str);
return *this;
}
boost::variant<std::string, void const*> var;
};
VariantWrapper bar;
bar = "foo";
std::cout << bar.var.which();
这样做将限制模板匹配仅限于文字字符串和字符数组,但仍然允许您使用(比方说) const char*
做一些不同的事情。不过,如果您想匹配符合c-字符串类别的所有内容,可以只使用const char*
。
发布于 2015-06-23 08:54:55
您可以从boost::variant<std::string, void const*>
派生自己的类,并提供隐式const *和string构造函数。
https://stackoverflow.com/questions/31008568
复制