What differences, if any, between C++03 and C++11 can be detected at run-time?

后端 未结 8 1403
深忆病人
深忆病人 2020-12-02 04:44

It is possible to write a function, which, when compiled with a C compiler will return 0, and when compiled with a C++ compiler, will return 1 (the trivial sulution with

相关标签:
8条回答
  • 2020-12-02 04:52

    This isn't quite a correct example, but it's an interesting example that can distinguish C vs. C++0x (it's invalid C++03 though):

     int IsCxx03()
     {
       auto x = (int *)0;
       return ((int)(x+1) != 1);
    }
    
    0 讨论(0)
  • 2020-12-02 04:52
    #include <utility>
    
    template<typename T> void test(T t) { t.first = false; }
    
    bool isCpp0x()
    {
       bool b = true;
       test( std::make_pair<bool&>(b, 0) );
       return b;
    }
    
    0 讨论(0)
  • 2020-12-02 04:55

    Though not so concise... In current C++, class template name itself is interpreted as a type name (not a template name) in that class template's scope. On the other hand, class template name can be used as a template name in C++0x(N3290 14.6.1/1).

    template< template< class > class > char f( int );
    template< class > char (&f(...))[2];
    
    template< class > class A {
      char i[ sizeof f< A >(0) ];
    };
    
    bool isCpp0x() {
      return sizeof( A<int> ) == 1;
    }
    
    0 讨论(0)
  • 2020-12-02 04:59

    I got an inspiration from What breaking changes are introduced in C++11?:

    #define u8 "abc"
    
    bool isCpp0x() {
       const std::string s = u8"def"; // Previously "abcdef", now "def"
       return s == "def";
    }
    

    This is based on the new string literals that take precedence over macro expansion.

    0 讨论(0)
  • 2020-12-02 05:07

    Unlike prior C++, C++0x allows reference types to be created from reference types if that base reference type is introduced through, for example, a template parameter:

    template <class T> bool func(T&) {return true; } 
    template <class T> bool func(...){return false;} 
    
    bool isCpp0x() 
    {
        int v = 1;
        return func<int&>(v); 
    }
    

    Perfect forwarding comes at the price of breaking backwards compatibility, unfortunately.

    Another test could be based on now-allowed local types as template arguments:

    template <class T> bool cpp0X(T)  {return true;} //cannot be called with local types in C++03
                       bool cpp0X(...){return false;}
    
    bool isCpp0x() 
    {
       struct local {} var;
       return cpp0X(var);
    }
    
    0 讨论(0)
  • 2020-12-02 05:11

    From this question:

    struct T
    {
        bool flag;
        T() : flag(false) {}
        T(const T&) : flag(true) {}
    };
    
    std::vector<T> test(1);
    bool is_cpp0x = !test[0].flag;
    
    0 讨论(0)
提交回复
热议问题