foool
foool

Reputation: 1552

A C++ class-function

A simple c++ file and the class TT has two methods.

#include <map>
#include <string>
#include <iostream>

using namespace std;

class TT{ 
    public:
        TT(const string& str);
        template<class T>T Read(const string& key)const;
        template<class T>T Read(const string& key, const T& value)const;
};

TT::TT(const string& str){
    cout<<str<<endl;
}

template<class T>T TT::Read(const string& key)const{
    std::cout<<key<<std::endl;
    return 1;
}

template<class T>T TT::Read(const string& key, const T& value)const{
    std::cout<<key<<'\t'<<value<<std::endl;
    return value;
}

int main(void){
    TT tt("First");

    tt.Read("Hello", 12);
    return 1;
}

If replace the

tt.Read("Hello world!", 12);

with

tt.Read("Hello world!");

in main()

G++ says:

new.cc:31: error: no matching function for call to ‘TT::Read(const char [5])’

Why G++ cann't find the Read(const string& key)const method?

Thanks!

Upvotes: 3

Views: 357

Answers (3)

Sean Cline
Sean Cline

Reputation: 7209

Your function template<class T>T Read(const string& key)const; is templated on type T but T only appears as the return type.

If it is your intention to manually bake a return type into your function (and it seems like it is from the appearance of return 1;), you can change the declaration to something like:

int Read(const string& key) const;

Otherwise you must specify the templated type manually in the call as so:

tt.Read<int>("Hello");

This boils down to the fact that a function cannot have a templated type deduced when that templated type appears solely in return.

The C++ standard says it in a way much less easy on the eyes in the section titled:

Explicit template argument specification [temp.arg.explicit]

If all of the template arguments can be deduced, they may all be omitted; in this case, the empty template argument list <> itself may also be omitted. In contexts where deduction is done and fails, or in contexts where deduction is not done, if a template argument list is specified and it, along with any default template arguments, identifies a single function template specialization, then the template-id is an lvalue for the function template specialization.

template<class X, class Y> X f(Y);

int i = f<int>(5.6); // Y is deduced to be double
int j = f(5.6); // ill-formed: X cannot be deduced

Upvotes: 1

user34537
user34537

Reputation:

I believe it is because when dealing with templates, the compiler would like to know what the return function is and it can't figure it out even though it returns 1 which is an int. Technically return 1 could be an error as it doesn't know what the return value SHOULD be.

Use tt.Read<int>("Hello");

Upvotes: 1

Yuushi
Yuushi

Reputation: 26080

You're trying to define a function that returns a T:

template<class T>
T TT::Read(const string& key) const
{
    std::cout << key << std::endl;
    return 1;
}

However, you always return an int from this function. You either need to call it like so:

tt.Read<int>("Hello");

Or remove the template definition, as it makes no sense here.

Upvotes: 6

Related Questions