Mey*_*sam 18 c++ boost boost-variant
我已经宣布boost::variant它接受三种类型:string,bool和int.以下代码显示我的变体接受const char*并将其转换为bool.boost::variant接受和转换不在其列表中的类型是否是正常行为?
#include <iostream>
#include "boost/variant/variant.hpp"
#include "boost/variant/apply_visitor.hpp"
using namespace std;
using namespace boost;
typedef variant<string, bool, int> MyVariant;
class TestVariant
: public boost::static_visitor<>
{
public:
void operator()(string &v) const
{
cout << "type: string -> " << v << endl;
}
template<typename U>
void operator()(U &v)const
{
cout << "type: other -> " << v << endl;
}
};
int main(int argc, char **argv)
{
MyVariant s1 = "some string";
apply_visitor(TestVariant(), s1);
MyVariant s2 = string("some string");
apply_visitor(TestVariant(), s2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
type:other - > 1
type:string - > some string
如果我从MyVariant中删除bool类型并将其更改为:
typedef variant<string, int> MyVariant;
Run Code Online (Sandbox Code Playgroud)
const char*不再转换为bool.这次它被转换为string,这是新的输出:
type:string - > some string
type:string - > some string
这表示variant尝试首先将其他类型转换为bool然后转换为string.如果类型转换是不可避免的并且应该总是发生,那么有没有办法将转换转换为string更高的优先级?
Gor*_*pik 13
这与boost::variantC++选择要应用的转换的顺序无关.在尝试使用用户定义的转换之前(请记住,这std::string是用户定义的类),编译器将尝试内置转换.有没有内置的转换,从const char*到int,但按照标准§4.12:
[...]指针类型的prvalue可以转换为bool类型的prvalue.
因此编译器很乐意将您转换const char*为a bool并且永远不会考虑将其转换为a std::string.
Ste*_*sop 12
我认为这不是特别关注的问题boost::variant,而是关于通过重载决策选择哪个构造函数.重载函数也会发生同样的事情:
#include <iostream>
#include <string>
void foo(bool) {
std::cout << "bool\n";
}
void foo(std::string) {
std::cout << "string\n";
}
int main() {
foo("hi");
}
Run Code Online (Sandbox Code Playgroud)
输出:
bool
Run Code Online (Sandbox Code Playgroud)
我不知道如何改变Variant的构造函数[编辑:正如James所说,你可以编写另一个在其实现中使用Variant的类.然后你可以提供一个const char*做正确事情的构造函数.
也许你可以改变Variant中的类型.另一个重载示例:
struct MyBool {
bool val;
explicit MyBool(bool val) : val(val) {}
};
void bar(MyBool) {
std::cout << "bool\n";
}
void bar(const std::string &) {
std::cout << "string\n";
}
int main() {
bar("hi");
}
Run Code Online (Sandbox Code Playgroud)
输出:
string
Run Code Online (Sandbox Code Playgroud)
不幸的是现在你必须写bar(MyBool(true))而不是foo(true).即使在你的变型的情况更糟糕string/bool/int,如果你只是将其更改为的变体string/MyBool/int,然后MyVariant(true)将调用int构造函数.
| 归档时间: |
|
| 查看次数: |
2926 次 |
| 最近记录: |