0

I have three files: main:

#include <iostream>
#include "Punkt.h"

int main() {

  const Punkt s1(0, 1);
  const Punkt s2(-5, 2);
  std::cout << "s1 " << s1.wsp<0>() <<  " " << s1.wsp<1>() << std::endl;
}

header:

#include <iostream>
#pragma once
class Punkt{
public:
    Punkt(int x, int y){
        m_x = x;
        m_y = y;
    }

    template <typename T> int wsp() const;
private:
    int m_x;
    int m_y;

};

cpp:

#include "Punkt.h"
#include <iostream>
using namespace std;
template <typename T> 
    int Punkt::wsp() const
{
    int obiekt(T);
    try{
        if (obiekt==1){
            return m_y;
        }
        if (obiekt==0){
            return m_x;
        }
        throw;
    }
    catch(...){
        std::cout << "Incorrect number" << std::endl;
    }
}

and the problem:

Main.cpp:46:35: error: no matching function for call to ‘Punkt::wsp() const’
   std::cout << "s1 " << s1.wsp<0>() <<  " " << s1.wsp<1>() << std::endl;

In file included from Main.cpp:39:0:
Punkt.h:11:28: note: candidate: template<class T> int Punkt::wsp() const
  template <typename T> int wsp() const;

Punkt.h:11:28: note:   template argument deduction/substitution failed:

I am starting with templates and I don't understand what is going on. When I change wsp to: 'template '(and the fuction ofc) it works fine. Do someone have any idea?

icnm
  • 7
  • 1
  • 4
  • `wsp<>` looks like a __value__ template, but is declared like a __type__ template. –  May 21 '18 at 16:24
  • @DeiDei you are correct that they will run in that issue soon enough, but that's not what this question is about. If this is a dupe, it's of some other question. –  May 21 '18 at 16:41

2 Answers2

2

When writing templates, typename is not just a random keyword you put in front of template arguments, it has a specific meaning.

Think of templates parameters as compile-time arguments. Like all arguments, they have a type and a name. typename means that the type of the template argument is going to be the name of some runtime type.

So, when you declare:

template <typename T> int wsp() const;

What you are saying is:

"wsp is function that takes a single compile-time argument, named T, that will be the name of a type"

When you call wsp<1>(), the compiler tells you: "hey! 1 is not the name of a type! You told me wsp<typename>, that makes no sense."

Fixing this is easy, you just change the type of the template argument from typename to int.

template <int T> int wsp() const;
0

Since wsp is a template, the parser is getting confused whether it is some expression (wsp < 0) > () or a function with a template parameter. That is why you need to specify obj.template wsp<0>() to disambiguate between the two cases.

Tanveer Badar
  • 5,438
  • 2
  • 27
  • 32