Is it possible to choose a C++ generic type parameter at runtime?

后端 未结 5 698
天命终不由人
天命终不由人 2021-02-14 07:52

Is there a way to choose the generic type of a class at runtime or is this a compile-time thing in C++?

What I want to do is something like this (pseudocode):

         


        
相关标签:
5条回答
  • 2021-02-14 08:11

    The closest you'll get is:

    template <typename T>
    void do_stuff_with_list
    {
        list<T> myList;
        ...
    }
    
    enum Type
    {
       Integer = 1,
       String
    };
    
    void do_stuff(Type type)
    {
        switch (type)
        {
        case Integer:
            do_stuff_with_list<int>();
            break;
        case String:
            do_stuff_with_list<string>();
            break;
        };
    }
    
    0 讨论(0)
  • 2021-02-14 08:25

    It's a compile time thing. Template parameter types must be known to the compiler at compile-time.

    That being, said, using certain template meta-programming techniques, you can choose one type or another AT compile-time, but only if all possible types are known at compile-time, and only if the condition for selecting a type can be resolved at compile time.

    For example, using partial specialization you could select a type at compile time based on an integer:

    template <typename T>
    class Foo
    { };
    
    template <int N>
    struct select_type;
    
    template<>
    struct select_type<1>
    {
        typedef int type;
    };
    
    template<>
    struct select_type<2>
    {
        typedef float type;
    };
    
    int main()
    {
        Foo<select_type<1>::type> f1; // will give you Foo<int>
        Foo<select_type<2>::type> f2; // will give you Foo<float>
    }
    
    0 讨论(0)
  • 2021-02-14 08:28

    I can't think of a situation where this would be useful, but…

    #include "boost/variant.hpp"
    #include <list>
    #include <string>
    
    boost::variant<std::list<int>, std::list<std::string> >
    unknown(int someval) {
        if (someval == 1)
            return boost::variant<std::list<int>, std::list<std::string> >(
                    std::list<int>());
        else if (someval == 2)
            return boost::variant<std::list<int>, std::list<std::string> >(
                    std::list<std::string>());
    }
    
    0 讨论(0)
  • 2021-02-14 08:32

    As others have also responded, the answer to your question is "No", C++ doesn't support dynamic typing at run-time. I just wanted to point out that depending on what you're trying to accomplish, you may be able to simulate this dynamic typing using a union, which is how the VARIANT type is implemented in COM.

    0 讨论(0)
  • 2021-02-14 08:33

    It is possible with Boost.Variant (fixed number of different types) or Boost.Any (a type that can store any type, basically your "void pointer" but with type information).

    It is also possible if String and Integer happened to be derived from a polymorphic base class. (But for that they would have to implement the same interface, which may or may not be possible in your case.)

    Generally, polymorphism is the easiest way to do it, and this is indeed used all the time.

    Variant and Any take quite a bit of work to be used: you still need somehow to obtain the contents as the right type they are storing. (Sort of as if you were to use down-casts to derived classes, instead of relying on polymorphic method calls.)

    0 讨论(0)
提交回复
热议问题