Robbin
Robbin

Reputation: 87

Generic function for a family of related functions (e.g. std::stoi, std::stof, std::stod etc)

I'd like to make a generic function for std::stoi, std::stof, std::stod etc.. like:

// std::string -> int
std::string str = "1000000";
int i = to_numeric<int>(str);

// std::string -> long
std::string str = "100000000000";
long i = to_numeric<long>(str);

// std::string -> float
std::string str = "10000.1";
float i = to_numeric<float>(str);

But I do not know how to make the partial specialization:

template<class T>
int to_numeric(const std::string &str, size_t *pos = 0, int base = 10) {
    return std::stol(str, pos, base);
};

template<>
long to_numeric<long>(const std::string &str, size_t *pos, base) {
    return std::stol(str, pos, base);
};

template<>
float to_numeric<float>(const std::string &str, size_t *pos) {
    return std::stof(str, pos);
};
// .....

Errors:

to_numeric.cpp:76:79: error: default argument specified in explicit specialization [-fpermissive]
to_numeric.cpp:76:12: error: template-id 'to_numeric<float>' for 'float to_numeric(const string&, size_t*)' does not match any template declaration
make: *** [build] Error 1

Upvotes: 6

Views: 1007

Answers (2)

Some programmer dude
Some programmer dude

Reputation: 409364

To start with, you have to make the non-specialized template function fully templated. That means you have to make the return type T. I also recommend that this non-specialized function doesn't do anything more than return e.g. T() (since it isn't specialized and don't know what function to call).

To continue, the to_numeric<float> specialization needs to have the same arguments as the non-specialized function, so you need to add the dummy baseargument.

Upvotes: 2

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153955

You specify a primary template which takes three arguments (str, pos, and base) but you try to specialize it with function templates taking just one argument. Clearly, this doesn't work: The specializations need to match the primary template.

Partial specializations of function templates are not [yet?] supported. If you need a partially specialized function template you need to do the partial specialization indirectly: You'd delegate to a class template and partially specialized that. The class template may have just one static function. Of course, in your example you don't use partial specialization but full specialization.

Upvotes: 2

Related Questions