Boost.Fusion run-time switch

前端 未结 5 1522
感情败类
感情败类 2021-02-13 17:43

I am reading the type of an object from a file:

enum class type_index { ... };
type_index typeidx = read(file_handle, type_index{});

Depending

5条回答
  •  执笔经年
    2021-02-13 18:07

    I think your existing solution isn't bad. At the point of // do generic stuff instead call into other functions overloaded on type

    boost::fusion::for_each(possible_types, [&](auto i) {
      if (i::typeidx != typeidx) { return; }
      doSpecificStuff(i);
    });
    
    void doSpecificStuff(const TypeA& a) { ... }
    void doSpecificStuff(const TypeB& b) { ... }
    ...
    

    AFAIK you can't quite get a switch, which is a little bit faster than the if...else structure here, but not substantially and is unlikely to be noticeable for a process you run while reading a file.

    Other options are all similar to this. Fusion or mpl random access containers or even std::tuple can be access with get<> but that requires a compile time index so you're building the cases up and still going through the indices with something like

    if (idx == 0) { doSpecificStuff(std::get<0>(possible_types)); }
    else if (idx == 1) ...
    ....
    

    Which could be done with recursive templates, like:

    template 
    void dispatchImpl(size_t idx)
    {
        if (idx >= std::tuple_size::value) return;
        if (idx == current) 
        {
            doSpecificStuff(std::get(possible_types));
            return;
        }
        dispatchImpl(idx);
    }
    void dispatch(size_t idx) { dispatchImpl<0>(idx); }
    

    The only alternative I'm aware of would be building an array of function pointers. See Optimal way to access std::tuple element in runtime by index. I don't think you really gain anything with that solution for your case and it's harder to follow.

    One advantage to your fusion::for_each solution is that it doesn't force your type indices to be continuous. As your application evolves you can add new types or remove old types easily and the code still works, which would be harder if you were trying to use the container index as your type index.

提交回复
热议问题