1

I am having a problem calling a template function with two template arguments.

I have a class and the class accepts objects of two different types. I don't know the types yet, so I left them as template parameters. I then store the objects in wrapper classes. In the end I want to be able to call a templated function with two template arguments, that takes my two objects. But I am perplexed at how to do this.

Here is a stripped down version of the code to explain my problem.

template<typename A, typename B>
void someTemplateFunction(A a, B b);


class Problem
{
  private:
    class WrapperA
    {
      public:
        virtual void doSomething() = 0;
    };

    template<typename A>
    class ConcreteWrapperA : public wrapperA
    {
      private:
        A a;
      public:
        ConcreteWrapperB(A b_) : a(a_) {}
        virtual void doSomething();
    };

    class WrapperB
    {
      public:
        virtual void doSomething() = 0;
    };

    template<typename B>
    class ConcreteWrapperB : public wrapperB
    {
      private:
        B b;
      public:
        ConcreteWrapperB(B b_) : b(b_) {}
        virtual void doSomething();
    };

    WrapperA *a;
    WrapperB *b;

  public:

    template<typename A>
    void setA(A a)
    {
      a = new ConcreteWrapperA<A>(a);
    }

    template<typename B>
    void setB(B b)
    {
      a = new ConcreteWrapperB<B>(b);
    }

    void call_someTemplateFunction(); // ??????? How do i do this?
};
4
  • Is every A or B types known? I mean, e.g., that you know that B can be int, long or short and nothing more. If yes, then I can provide an answer. On the other hand if you can set both with one function, then of course use 1st answer. Commented Sep 6, 2012 at 20:33
  • Unfortunately, the types of A and B are not know. I though about using boost::variant together with visitors. But that doesn't seem to work. Commented Sep 7, 2012 at 10:14
  • boost::variant requires that all possible types are known before using boost::variant. It is exactly what I asked before. Sorry for asking twice the same question, maybe my previous Q was not clear: Do you know all possible types which can be used for calling either Problem::setA or Problem::setB? Commented Sep 7, 2012 at 10:46
  • The possible types of A and B are not known. I am developing a library and I don't know in advance what concrete types the user will pass as A and B. Commented Sep 7, 2012 at 10:53

1 Answer 1

2

The problem is that you've type-erased both types A and B separately, so there's nowhere in the translation of your code that both types A and B are known.

If you can write a single function template<typename A, typename B> void set(A, B) then you could capture the pair type <A, B> at that point.

Alternatively, would it be possible for someTemplateFunction to operate without knowing both types A and B at the same time?


This is an issue fundamental to the design of C++ as a single-pass, separate compilation language.

Suppose that your program has three compilation units; A.cpp calls setA with a range of types T[A], B.cpp calls setB with another range of types T[B], and C.cpp owns the Problem object and wants to call someTemplateFunction. Then there's no time during compilation when the compiler knows both the range of types in A.cpp and the range of types in B.cpp, so it can't instantiate someTemplateFunction with the appropriate cross-product T[A] x T[B].

Sign up to request clarification or add additional context in comments.

1 Comment

I think, I understand your answer. In practice I could probably know both types A and B at the same time, but I wanted to be able to add multiple objects of B and maybe store them in a list without having to always pass A as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.