是否有可能从歧视联盟中自动提取类型?

时间:2015-06-12 22:07:20

标签: c++ c++11 discriminated-union

是否可以提取区分联合的类型来初始化“自动”变量?你将类型传递给模板很容易,但我想要一些“自动”。使用访问者函数或使用有界类型列表(例如mpl :: vector)的解决方案会很棒。

示例如下所示:

session.query

任何可能的解决方案都将不胜感激!

由于

3 个答案:

答案 0 :(得分:1)

您正在寻找Boost.TypeErasure图书馆。这将让您以自然的方式传输任何流。从教程:

any<
    mpl::vector<
        copy_constructible<>,
        typeid_<>,
        incrementable<>,
        ostreamable<>
    >
> x(10);
++x;
std::cout << x << std::endl; // prints 11

x这里可以是满足给定概念的任何类型。

如果这不是您想要的,那么Boost还有一个名为Variant的区别联合库,它有一个访问者界面。

答案 1 :(得分:0)

通常,当您覆盖自定义类类型的全局流运算符时,您应该根据对成员方法的调用来实现它们,并让类决定如何自行传输,例如:

struct d_union {
    ...
    void outputTo(std::ostream &os) const {
        if (auto ip = get_pointer<int>())
            os << *ip;
        else if (auto fp = get_pointer<float>())
            os << *fp;
        ...
    }
    ...
};

std::ostream& operator<<(std::ostream &os, const d_union &u) {
    u.outputTo(os);
    return os;
}

话虽如此,如果你在调用operator<<时想要一些更多“自动”,也许你可以尝试这样的东西(不完美,但接近你可能的正在考虑考虑d_union在运行时不知道它是什么,如果你添加了operator=,那么它甚至可以动态地改变类型):

typedef void (*pOutputProc)(const d_union&, std::ostream&);

template <typename T>
void outputProc(const d_union &u, std::ostream &os)
{
    os << *(u.get_pointer<T>());
}

std::unordered_map<std::type_index, pOutputProc> outputProcs;

template <typename T>
void registerOutputProc()
{
    outputProcs[std::type_index(typeid(T))] = &outputProc<T>;
}

void registerOutputProcs()
{
    registerOutputProc<int>();
    registerOutputProc<float>();
    ...
}
#pragma startup registerOutputProcs

struct d_union {
    ...
    void outputTo(std::ostream &os) const {
        pOutputProc proc = outputProcs[std::type_index(*_type_id)];
        if (proc) proc(*this, os);
    }
    ...
};

std::ostream& operator<<(std::ostream &os, const d_union &u) {
    u.outputTo(os);
    return os;
}

然后,您只需要使用您希望registerOutputProcs()支持的各种数据类型填充d_union

答案 2 :(得分:0)

一般来说,这是不可能的,因为C ++不是动态类型语言。

在特定情况下,(在您的情况下)operator<<()需要检查type_info并根据实际存在的类型执行操作。其局限性在于,有必要对struct中可能存储的类型进行硬编码 - 如果要添加对不同类型的支持,则需要添加代码并重建程序。

auto依赖编译器在编译时知道类型。 type_info在运行时获取值。