提高::变种 - 为什么“为const char *”转换为“布尔”?(boost::variant

2019-07-03 15:48发布

我已经宣布boost::variant ,它接受三种类型: stringboolint 。 下面的代码表明我的变种接受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;
}

输出:

类型:其它 - > 1
类型:字符串 - >一些字符串

如果我从MyVariant删除布尔类型和它改成这样:

typedef variant<string, int> MyVariant;

const char*没有更多的转换为bool 。 这一次,它会转换为string ,这是新的输出:

类型:字符串 - >一些字符串
类型:字符串 - >一些字符串

这表明, variant会尝试先转换成其他类型的bool ,然后string 。 如果类型转换是不可避免的事情,应该经常发生,有没有什么办法让转换为string更高的优先级?

Answer 1:

我不认为这是什么特别做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");
}

输出:

bool

我不知道的方式来改变什么构造一个变种[编辑:詹姆斯说,你可以写一个使用变在其执行其他类。 然后,你可以提供一个const char*构造函数,做正确的事。]

也许你可以改变的变异类型。 另一个重载例如:

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");
}

输出:

string

不幸的是,现在你必须写bar(MyBool(true))而不是foo(true) 。 即使在你的变型的情况更糟糕的string/bool/int ,如果你只是将其更改为的变体string/MyBool/int然后MyVariant(true)将调用int构造。



Answer 2:

这有什么好做boost::variant ,但与顺序C ++选择适用的转换。 尝试使用用户定义的转换之前(记住std::string是一个用户定义的类用于此目的),编译器将尝试内置转换。 没有来自内置转换const char*int ,但按照标准§4.12:

的prvalue [...]指针[...]类型可以转换为bool类型的prvalue。

因此,编译您愉快地转换const char*bool和从来没有得到考虑将其转换为一个std::string



文章来源: boost::variant - why is “const char*” converted to “bool”?