Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't C++ deduce template type from assignment?

Tags:

int x = fromString("test") :could not deduce template argument for 'ValueType'

int x = fromString<int>("test") : works fine as expected

So why does the compiler struggle here? I see it with all kinds of real template functions, not just this silly example. It must be a feature of the language, but what?

like image 905
Mr. Boy Avatar asked Nov 17 '11 10:11

Mr. Boy


People also ask

What is template argument deduction?

Template argument deduction is used when selecting user-defined conversion function template arguments. A is the type that is required as the result of the conversion. P is the return type of the conversion function template.

How do I restrict a template type in C++?

There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.

What is C++ type deduction?

Type inference or deduction refers to the automatic detection of the data type of an expression in a programming language. It is a feature present in some strongly statically typed languages. In C++, the auto keyword(added in C++ 11) is used for automatic type deduction.

What is a non type template parameter?

A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument. A non-type parameter can be any of the following types: An integral type. An enumeration type. A pointer or reference to a class object.


2 Answers

You can't deduce based on the return type. You can, however, implement a workaround with similar syntax, using the overloaded cast operator:

#include <iostream>
#include <sstream>
#include <string>
using namespace std;

class FromString{
private:
    string m_data;
public:
    FromString(const char*data) : m_data(data) {} 

    template<typename T>
    operator T(){
        T t;
        stringstream ss(m_data);
        ss >> t;
        return t;
    }

};

template<> FromString::operator bool(){
    return (m_data!="false"); //stupid example
}

int main(){

    int ans = FromString("42");    
    bool t = FromString("true");
    bool f = FromString("false");

    cout << ans << " " << t << " " << f << endl;

    return 0;
}

Output:

42 1 0
like image 111
Vlad Avatar answered Sep 18 '22 17:09

Vlad


C++ doesn't do type inference on the return value. I.e., the fact that it is being assigned to an int isn't used in template parameter deduction.

(Removed edit, since someone else presented the overloaded cast solution already.)

like image 33
Marcelo Cantos Avatar answered Sep 17 '22 17:09

Marcelo Cantos