Template argument deduction

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • tavianator
    New Member
    • Dec 2006
    • 38

    #1

    Template argument deduction

    I understand that template arguments cannot always be deduced to reference types; foo(0) deduces to foo<int>, not foo<const int&>, while bar(baz<int&>() ) will deduce to bar<int&> if it takes a baz<T> argument. It seems sensible to assume that this code would work, but it doesn't:

    Code:
    template<typename T> class foo
    {
    };
    
    template<typename T> void bar(foo<T>&, type)
    {
    }
    
    int main()
    {
      foo<int&> x;
      int y;
      bar(x, y);
    }
    Is there any way around this, bearing in mind that my real problem concerns template constructors, so there is no possibility of explicitly specifing the template parameter, and there are too many arguments to provide T& and const T& overloads for every argument?
  • tavianator
    New Member
    • Dec 2006
    • 38

    #2
    "error: no matching function for call to ‘bar(foo<int&>& , int&)’", which is exactly signature of the function bar<int&>.

    P.S. Sorry about putting this in another post, but when I put it in the first one, I got a 404 not found error. Wierd, eh?

    Comment

    • tavianator
      New Member
      • Dec 2006
      • 38

      #3
      I figured it out, so I am posting it here in case anyone else stumbles accross the same problem I had. I believe that std::tr1::tuple (and boost::tuple) use this technique.

      Create a struct like this:
      Code:
      template <typename t> struct addcref
      {
        typedef const t& type;
      };
      
      template <typename t> struct addcref <t&>
      {
        typedef t& type;
      };
      
      template <typename t> struct addcref <const t&>
      {
        typedef const t& type;
      };
      Then just pass arguments like so (this is also useful when forewording function arguments):

      Code:
      template <typename t> class foo;
      template <typename t>
        void bar(foo<t> a, typename addcref<t>::type b);
      template <typename arg>
        void baz(void (&fn)(arg), typename addcref<arg>::type param);

      Comment

      • Ganon11
        Recognized Expert Specialist
        • Oct 2006
        • 3651

        #4
        Nice to see you got the correct answer. Sorry we couldn't help you, but thanks for posting the solution for others!

        Hopefully if you have more questions in the future, we will be able to help you out.

        Comment

        Working...