Search code examples
c++c++98

How can I decide if I want to return a pair with an integer key or string key inside a template function


I'm trying to figure out what type the template currently is, I have looked in stackoverflow but did not find a solid answer. Basically I want to create an #if #else #endif and depending on the type of the template put code.

Here is my code

#include <map>
#include <iostream>

template <typename T>
#define IS_INT std::is_integral<T::first_type>::value
T create_a_pair()
{
    #if IS_INT
    return std::make_pair(5, typename T::second_type()));
    #else
    return T();
    #endif
}

int main()
{
    std::cout << create_a_pair<std::pair<int, int> >().first << std::endl;
    std::cout << create_a_pair<std::pair<std::string, int> >().first << std::endl;
}

I tried this also but I got a compile time error saying I can't use integer 5 because the type is a string.

#include <map>
#include <iostream>

template <typename T>
T create_a_pair()
{
    if (std::is_integral<T::first_type>::value)
        return std::make_pair(5, typename T::second_type()));
    return T();
}

int main()
{
    std::cout << create_a_pair<std::pair<int, int> >().first << std::endl;
    std::cout << create_a_pair<std::pair<std::string, int> >().first << std::endl;
}

Solution

  • Whenever I need some type_traits from newer C++ standards, I steal them and adapt them to the older standard (if needed).

    Example:

    namespace traits98 {
    struct false_type { static const bool value; };
    const bool false_type::value = false;
    
    struct true_type { static const bool value; };
    const bool true_type::value = true;
    
    template<class T, class U> struct is_same : false_type {};
    template<class T> struct is_same<T, T> : true_type {};
    
    template<bool B, class T = void> struct enable_if {};
    template<class T> struct enable_if<true, T> { typedef T type; };
    } // namespace traits98
    

    With those, you can easily make overloads:

    #include <iostream>
    #include <string>
    #include <utility>
    
    using namespace traits98;
    
    template <typename F, typename S>
    typename enable_if<!is_same<int, F>::value, std::pair<F,S> >::type
    create_a_pair() { return std::pair<F,S>(); }
    
    template <typename F, typename S>
    typename enable_if<is_same<int, F>::value, std::pair<F,S> >::type
    create_a_pair() {
        return std::make_pair(5, S());
    }
    
    int main() {
        std::cout << create_a_pair<int, int>().first << '\n';
        std::cout << create_a_pair<std::string, int>().first << '\n';
    }