I am trying to understand how does SFINAE work in C 98.
My aim is to write a simple template function that would only be called when
an integer is passed. But the plan is to do it without specializing a function for typename T = int, but definining a template function with a dummy parameter that checks wether the pased element is an integer. Heres my toy code :
// header.h
#include <iostream>
#include <cstddef>
struct false_type {
static const bool value = false;
};
struct true_type {
static const bool value = true;
};
template < bool, typename T >
struct enable_if
{};
template <typename T>
struct enable_if<true, T>
{ typedef T type; };
template <typename T>
struct is_integral : false_type {};
template <>
struct is_integral<int> : true_type {};
/* ... more is_integral specializations ... */
template < typename T >
void print(T& value, typename enable_if<!is_integral<T>::value,T>::type* = 0)
{
std::cout << "FIRST " << value << std::endl;
}
template < typename T >
void print(T& value)
{
std::cout << "SECOND " << value << std::endl;
std::cout << std::boolalpha;
std::cout << is_integral<T>::value << std::endl;
}
// main.cpp
#include "header.hpp"
int main() {
int a = 123;
print<int>(a);
}
It is compiled as follows : g -Wall -Wextra -Werror -std=c 98 -pedantic -g3 -Wno-c 0x-compat main.cpp
.
I took the enable_if syntax from this question's first answer, which needed for an implementation of enable_if
and is_integral
to be carried out in C 98 (<type_traits> is not a C 98 header).
My problem is that this program outputs:
SECOND 123
true
My question is, why does this happen? I expected the first implementation of print to be called. Is my approach impossible (i.e. this can only be done by specializing a generic print function to int), or am I doing something wrong ?
CodePudding user response:
My aim is to write a simple template function that would only be called when an integer is passed.
There is no need to provide 2 overloads. You can just remove the !
and have the first primary template as shown below:
template < typename T >
void print(T& value, typename enable_if<is_integral<T>::value,T>::type* = 0)
{
std::cout << "FIRST " << value << std::endl;
}
int main() {
int a = 123;
print<int>(a); //works
//print<double>(4.4); //doesn't work
//print<std::string>(std::string("f")); //doesn't work
//print(3.3); //doesn't work
double d = 3.3;
//print(d); //doesn't work
}