Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cryptic error on templates

I am rather stumped by the error message I am seeing for a piece of code I am working on currently. I've tried to extract the most relevant pieces of the code to make it easy on the eyes.

The error I see:

error: no matching function for call to ‘Map(Print&, std::shared_ptr< LinkedList< int> >&)
note: template argument deduction/substitution failed: cannot convert ‘p’ (type ‘Print’) to type ‘int

Why is the compiler trying to cast Print to int at all?

template<typename T>
class LinkedList
{
public:
  using NodeType = std::shared_ptr<LinkedList>;
  ... Other things
}

template<class Func, typename T>
typename LinkedList<T>::NodeType Map(Func func, typename  LinkedList<T>::NodeType seq)
{
  // Some stuff
}

class Print
{
 public:

 int operator()(int i)
 {
     cout << i << endl;
     return i;
 }
};

void main()
{
  Print p;
  auto one = std::make_shared< LinkedList <int>> ();
  auto result = Map<int>(p, one);  << ---- Error
}

gcc 4.8.4

Thanks for reading.

like image 843
Cyrax Avatar asked Apr 10 '26 18:04

Cyrax


1 Answers

If I was doing this, I would define Map as an inline friend of LinkedList. This removes problems with dependent type deduction, so you can call Map without any explicit template parameters.

Keep in mind that the only way for the compiler to find a function defined like this is with Argument-Dependent Lookup -- so it only works when a LinkedList object is passed as one of the function's arguments. Also inline friends seem to freak people out.

But it goes a long way to clean up and simplify the code.

#include <iostream>
#include <memory>

template<typename T>
class LinkedList
{
public:
    using NodeType = std::shared_ptr<LinkedList>;


    template <typename Func>
    friend NodeType Map(Func func, NodeType seq) {
        return seq;
    }

};

class Print
{
public:
    int operator()(int i)
    {
        std::cout << i << std::endl;
        return i;
    }
};

int main()
{
  Print p;
  auto one = std::make_shared< LinkedList<int> >();
  auto result = Map(p, one);
}
like image 187
Christopher Oicles Avatar answered Apr 12 '26 08:04

Christopher Oicles