3

In my recent QA, I was suggested to implement my own is_same for C++03 since the standard version is a part of C++11. The implementation was

template <typename T, typename U>
struct is_same {
    static const bool value = false;
};

template <typename T>
struct is_same <T, T> {
    static const bool value = true;
};

I want that it should be used only if it is not defined in the std namespace. For instance, can it be wrapped in a preprocessor block like this ?

#if !defined(std::is_same)
// define is_same here
#endif

I want to avoid these errors

error: 'is_same' is not a member of 'std' // C++03

error: reference to 'is_same' is ambiguous // C++11

Community
  • 1
  • 1
Shreevardhan
  • 12,233
  • 3
  • 36
  • 50
  • possible duplicate of [How to determine the version of the C++ standard used by the compiler?](http://stackoverflow.com/questions/2324658/how-to-determine-the-version-of-the-c-standard-used-by-the-compiler) – Mikhail Jul 16 '15 at 14:54
  • @Mikhail I mentioned that I have used `__cplusplus`, but it doesn't help in windows platform. – Shreevardhan Jul 16 '15 at 14:57
  • 1
    From what I see, it should be defined. It seems like it is not correctly defined, though: https://connect.microsoft.com/VisualStudio/feedback/details/763051/a-value-of-predefined-macro-cplusplus-is-still-199711l – Mikhail Jul 16 '15 at 15:02
  • Why not to let the build system handle things like checking the compiler, e.g. using [CMake](http://stackoverflow.com/a/14934542)? – nils Jul 19 '15 at 14:44

1 Answers1

6

No, you can't detect whether your implementation provides std::is_same, because that would mean including <type_traits>, which does not exist in C++03. Even if you could get around that obstacle, the metaprogramming contortions needed to detect it would not be worth it.

The best you can do is to heuristically check a combination of predefined macros:

#if __cplusplus >= 201103L || _MSC_VER >= 1400 || defined(__GXX_EXPERIMENTAL_CXX0X__)
    #include <type_traits>
    #define HAS_STD_IS_SAME
#endif

namespace your_project
{
    #ifdef HAS_STD_IS_SAME
        using std::is_same;
    #else
        template <typename T, typename U> struct is_same { static const bool value = false; };
        template <typename T> struct is_same <T, T> { static const bool value = true; };
    #endif
}

But there is nil benefit in doing this, because all implementations will implement is_same in the same manner as the one you have provided, anyway.

Oktalist
  • 14,336
  • 3
  • 43
  • 63