template type only known at runtime

Discussion in 'C++' started by Ralf Goertz, Nov 18, 2008.

  1. Ralf Goertz

    Ralf Goertz Guest

    Hi,

    I want to do able to declare an object bar of a templated class foo
    where the actual template type of foo is only know at runtime:

    -----

    #include <string>

    template <class T> class foo {
    T x;
    public:
    void do_something_depending_on_type_of_T(){

    ...
    };
    }

    int main(int argc, char *argv[]) {
    if (argc==1) //default type string should be used
    foo<std::string> bar;
    else //use class int
    foo<int> bar;
    bar.do_something_depending_on_type_of_T();
    return 0;
    }

    -----

    I know it doesn't work like this but is it possible at all?

    Ralf
     
    Ralf Goertz, Nov 18, 2008
    #1
    1. Advertising

  2. Ralf Goertz

    Leandro Melo Guest

    On 18 nov, 08:51, Ralf Goertz
    <> wrote:
    > Hi,
    >
    > I want to do able to declare an object bar of a templated class foo
    > where the actual template type of foo is only know at runtime:
    >
    > -----
    >
    > #include <string>
    >
    > template <class T> class foo {
    >     T x;
    > public:
    >     void do_something_depending_on_type_of_T(){
    >
    >         ...
    >     };
    >
    > }
    >
    > int main(int argc, char *argv[]) {
    >     if (argc==1) //default type string should be used
    >         foo<std::string> bar;
    >     else //use class int
    >         foo<int> bar;
    >     bar.do_something_depending_on_type_of_T();
    >     return 0;
    >
    > }
    >


    Template based code is constructed at compile time (static
    polymorphism). If you need dynamic polymorphism use virtual functions.
    However, your code has a general C++ problem (not specific to
    templates). The line bar.do_something_depending_on_type_of_T(); will
    generate an error because bar is undefined. This would happen even if
    bar was not a template.

    I don't know if this is the best design for you. But the closest I can
    get to it is through template specialization:

    emplate <class T> class foo
    {
    public:
    void do_something()
    {} //You don't need trailing semi-colon here.
    }; //You need it here though.

    template <> class foo<std::string>
    {
    public:
    void do_something()
    { /*Implementation for string */ }
    };

    template <> class foo<int>
    {
    public:
    void do_something()
    { /*Implementation for int */ }
    };

    int main(int argc, char *argv[])
    {
    foo<std::string> stringBar;
    foo<int> intBar;
    if (argc==1)
    stringBar.do_something();
    else
    intBar.do_something();
    return 0;
    }

    --
    Leandro T. C. Melo
     
    Leandro Melo, Nov 18, 2008
    #2
    1. Advertising

  3. Ralf Goertz

    maverik Guest

    On Nov 18, 1:51 pm, Ralf Goertz
    <> wrote:

    > I know it doesn't work like this but is it possible at all?


    It wouldn't work even if you solve your problems with templates
    because of scoping:

    > int main(int argc, char *argv[]) {
    > if (argc==1) //default type string should be used
    > foo<std::string> bar;
    > else //use class int
    > foo<int> bar;
    > bar.do_something_depending_on_type_of_T();


    bar is undefined here (out of scope).

    > return 0;
    > }
     
    maverik, Nov 18, 2008
    #3
  4. Ralf Goertz

    maverik Guest

    On Nov 18, 1:51 pm, Ralf Goertz
    <> wrote:
    > Hi,
    >
    > I want to do able to declare an object bar of a templated class foo
    > where the actual template type of foo is only know at runtime:


    The most painless solution I think looks like:

    int main(int argc, char *argv[]) {
        if (argc == 1) {
            foo<std::string> bar;
    bar.do_something_depending_on_type_of_T();
    } else {
            foo<int> bar;
    bar.do_something_depending_on_type_of_T();
    }
        return 0;
    }

    Of course, may be a better solution also exists.
     
    maverik, Nov 18, 2008
    #4
  5. Ralf Goertz

    Ralf Goertz Guest

    maverik wrote:

    > On Nov 18, 1:51 pm, Ralf Goertz
    > <> wrote:
    >
    >> I know it doesn't work like this but is it possible at all?

    >
    > It wouldn't work even if you solve your problems with templates
    > because of scoping:


    I know about the scoping problem. The code was just there to illustrate
    what I want which was hard for me to describe in prose. The problem is
    similar to one I had a year ago or so. I had wanted to create a
    reference to cin or an ifstream object depending on how the program was
    invoked. At that time I was wondering why C++ didn't have a deferred
    intialization feature for references like

    istream &config;
    ifstream ifs;
    if (config_is_read_from_cin) config=cin; else config=ifs;

    It can be done with pointers why not with references. Anyway, it seems I
    have to use the apprach you gave in the other posting, thanks, also to
    Leandro.

    Ralf
     
    Ralf Goertz, Nov 18, 2008
    #5
  6. Ralf Goertz

    Ralf Goertz Guest

    Hendrik Schober wrote:

    > Ralf Goertz wrote:
    >> Hi,
    >>
    >> I want to do able to declare an object bar of a templated class foo
    >> where the actual template type of foo is only know at runtime:

    >
    > If the type is only known at run-time, you need run-time
    > polymorphy, which is done using virtual functions and
    > inheritance. However, that doesn't mean you can't use
    > templates at all:
    >
    > class foo_base {
    > public: virtual void do_something_depending_on_type_of_T() = 0; };
    > virtual void do_something_depending_on_type_of_T() = 0;
    > };
    >
    > template< typename T >
    > class foo : public foo_base {
    > public:
    > virtual void do_something_depending_on_type_of_T() {}
    > };



    Actually, I just need two different types for the template,
    foo<std::string> and foo<int>. The only difference is the id type I get
    from a database, it can be either integer or char and is known only at
    runtime. If it is numeric I still have to do some calculations with it
    (so I can't just sql-cast it to char and use std::string in my program).
    Also, the way of writing back the data to the db differs because of
    quoting. "id" must be part of the class as I also need it for
    std::map<T,double> within class foo. But wrapping it in another template
    function as you also suggested seems to be the way to go.

    Thanks for the ternary ?: suggestion in the other posting!

    Ralf
     
    Ralf Goertz, Nov 19, 2008
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Guest
    Replies:
    1
    Views:
    591
    Lowell Heddings
    Dec 9, 2004
  2. Marco Herrn
    Replies:
    14
    Views:
    498
    Peter Otten
    Sep 16, 2003
  3. Samuel
    Replies:
    4
    Views:
    271
    Carsten Haese
    Oct 4, 2006
  4. Terence Wilson
    Replies:
    4
    Views:
    370
    Thomas J. Gritzan
    May 11, 2007
  5. Andrew Libby
    Replies:
    2
    Views:
    97
    Andrew Libby
    Oct 23, 2006
Loading...

Share This Page