I have a problem with SFINAE. I'm missing something important and reading other issues do not help :(
Here is the code:
#include <string>
#include <type_traits>
#include <iostream>
// version with template class
template<typename T, typename = std::enable_if_t<
std::is_integral<std::remove_reference_t<T>>::value
|| std::is_floating_point<std::remove_reference_t<T>>::value
>
>
struct to_my_string
{
std::string operator()(T numerical)
{
return std::to_string(numerical);
}
};
template<typename T, typename = std::enable_if_t< std::is_same<T, std::string>::value > >
struct to_my_string
{
std::string operator()(T str)
{
return "'" + str + "'";
}
};
// version with template method
template<typename T, typename = std::enable_if_t<
std::is_integral<std::remove_reference_t<T>>::value
|| std::is_floating_point<std::remove_reference_t<T>>::value
>
>
std::string to_string_method(T numerical)
{
return std::to_string(numerical);
}
template<typename T, typename = std::enable_if_t< std::is_same<T, std::string>::value > >
std::string to_string_method(T str)
{
return "'" + str + "'";
}
int main()
{
std::cout << "start" << std::endl;
return 0;
}
I have pasted two approaches - a class and a method approach. Both yields similar errors: Here are errors for g++ (clang gives similar errors):
g++ --std=c++14 sfinae_failure.cpp
sfinae_failure.cpp:21:12: error: redefinition of default argument for ‘class<template-parameter-1-2>’
struct to_my_string
^
sfinae_failure.cpp:7:26: note: original definition appeared here
template<typename T, typename = std::enable_if_t<
^
sfinae_failure.cpp:43:17: error: redefinition of ‘template<class T, class> std::__cxx11::string to_string_method(T)’
std::string to_string_method(T str)
^
sfinae_failure.cpp:37:17: note: ‘template<class T, class> std::__cxx11::string to_string_method(T)’ previously declared here
std::string to_string_method(T numerical)
^
My main question is why it does not work, even when I'm using T type in enable_if_t. What am I missing?
Additional side question is - I thought that template classes/methods are instantiated, when they are used. As you can see in the main method - they are not.
I would really appreciate some help here even if that topic was touched many many times...