C和x2B之间有什么区别(如有)+;03和C++;11可以在运行时检测到吗? 可以编写一个函数,当用C编译器编译时,它将返回0,并且当用C++编译器编译时,它将返回1(平凡的Sulink)。 #ifdef u cplusplus不感兴趣)

C和x2B之间有什么区别(如有)+;03和C++;11可以在运行时检测到吗? 可以编写一个函数,当用C编译器编译时,它将返回0,并且当用C++编译器编译时,它将返回1(平凡的Sulink)。 #ifdef u cplusplus不感兴趣),c++,c++11,c++03,language-detection,C++,C++11,C++03,Language Detection,例如: int isCPP() { return sizeof(char) == sizeof 'c'; } 当然,只有当sizeof(char)与sizeof(int) 另一个更便携的解决方案如下: int isCPP() { typedef int T; { struct T { int a[2]; }; return sizeof(T) == sizeof(struct T);

例如:

int isCPP()
{
    return sizeof(char) == sizeof 'c';
}
当然,只有当
sizeof(char)
sizeof(int)

另一个更便携的解决方案如下:

int isCPP()
{
    typedef int T;
    {
       struct T 
       {
           int a[2];
       };
       return sizeof(T) == sizeof(struct T);
    }
}
我不确定这些例子是否100%正确,但你明白了。我相信还有其他方法可以编写相同的函数

在运行时可以检测到C++03和C++11之间的哪些差异(如果有)?换言之,是否可以编写一个类似的函数,返回一个布尔值,指示它是由符合标准的C++03编译器还是C++11编译器编译的

bool isCpp11()
{ 
    //???
} 
核心语言 使用
::
访问枚举数:

template<int> struct int_ { };

template<typename T> bool isCpp0xImpl(int_<T::X>*) { return true; }
template<typename T> bool isCpp0xImpl(...) { return false; }

enum A { X };
bool isCpp0x() {
  return isCpp0xImpl<A>(0);
}
此外,字符串文字不再转换为
char*

bool isCpp0xImpl(...) { return true; }
bool isCpp0xImpl(char*) { return false; }

bool isCpp0x() { return isCpp0xImpl(""); }
不过,我不知道在真正的实现中实现这个功能的可能性有多大。利用
auto

struct x { x(int z = 0):z(z) { } int z; } y(1);

bool isCpp0x() {
  auto x(y);
  return (y.z == 1);
}
以下内容基于这样一个事实:在C++0x中,
运算符int&
是到
int&
的转换函数,在C++03中是到
int
的转换,后跟逻辑and

struct Y { bool x1, x2; };

struct A {
  operator int();
  template<typename T> operator T();
  bool operator+();
} a;

Y operator+(bool, A);

bool isCpp0x() {
  return sizeof(&A::operator int&& +a) == sizeof(Y);
}

标准库 检测C++0x'
std::basic_ios中缺少
运算符void*

struct E { E(std::ostream &) { } };

template<typename T>
bool isCpp0xImpl(E, T) { return true; }
bool isCpp0xImpl(void*, int) { return false; }

bool isCpp0x() {
  return isCpp0xImpl(std::cout, 0);
}
结构E{E(std::ostream&){}; 模板 bool iscp0ximpl(E,T){返回true;} bool iscp0ximpl(void*,int){return false;} bool isCpp0x(){ 返回iscp0ximpl(std::cout,0); }
这不是一个非常正确的示例,但它是一个有趣的示例,可以区分C和C++0x(尽管它是无效的C++03):


使用
>>
结账模板的新规则进行检查如何:

#include <iostream>

const unsigned reallyIsCpp0x=1;
const unsigned isNotCpp0x=0;

template<unsigned>
struct isCpp0xImpl2
{
    typedef unsigned isNotCpp0x;
};

template<typename>
struct isCpp0xImpl
{
    static unsigned const reallyIsCpp0x=0x8000;
    static unsigned const isNotCpp0x=0;
};

bool isCpp0x() {
    unsigned const dummy=0x8000;
    return isCpp0xImpl<isCpp0xImpl2<dummy>>::reallyIsCpp0x > ::isNotCpp0x>::isNotCpp0x;
}

int main()
{
    std::cout<<isCpp0x()<<std::endl;
}
我的灵感来自:


这是基于优先于宏扩展的新字符串文字。

< P>不同于先前的C++,C++ +0x允许引用类型从引用类型创建,如果该基引用类型通过模板参数引入:例如:/P>
template <class T> bool func(T&) {return true; } 
template <class T> bool func(...){return false;} 

bool isCpp0x() 
{
    int v = 1;
    return func<int&>(v); 
}
template bool func(T&){return true;}
模板bool func(…){return false;}
bool isCpp0x()
{
int v=1;
返回函数(v);
}
不幸的是,完美的转发是以破坏向后兼容性为代价的

另一个测试可以基于现在允许的本地类型作为模板参数:

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);
}
无法在C++03中使用本地类型调用模板bool cpp0X(T){return true;}// bool cpp0X(…){return false;} bool isCpp0x() { 结构局部{}var; 返回cpp0X(var); } 虽然不那么简洁。。。 在当前C++中,类模板名本身被解释为类型名。 (不是模板名称)在该类模板的作用域中。 另一方面,类模板名称可以用作中的模板名称 C++0x(N329014.6.1/1)

templateclass>charf(int);
模板char(&f(…)[2];
模板<类>A类{
字符i[sizeof f(0)];
};
bool isCpp0x(){
返回大小f(A)==1;
}
来自:

struct
{
布尔旗;
T():标志(假){}
T(常数T&):标志(真){
};
性病媒试验(1);
布尔是_cpp0x=!测试[0]。标志;
#包括
模板无效测试(T){T.first=false;}
bool isCpp0x()
{
布尔b=真;
测试(标准:制造成对(b,0));
返回b;
}

不错。我可以确认,这个解决方案在g++(GCC)4.6.0中可以工作,包括有和没有-std=c++0x。对于MSVC 2005以后的版本,它返回
true
,并且在MSVC 2003中出现编译错误。哦,天哪,它们破坏了向后兼容性@约翰尼斯:这是你几周来最开心的一次,不是吗?;-]我觉得这些都很有趣,但我认为最聪明的是
(…)
vs
(char*)
调用。我真的很喜欢!从技术上讲,这取决于
sizeof(int)!=1
为真。在具有异常大的
char
s的0x系统上,结果可能是相同的。不过,这仍然是一个巧妙的技巧。@Dennis-
char
总是一个字节though@Node:一个字节并不总是8位。@Node
sizeof(char)
根据定义总是1位。但是
字符位
(在limits.h中定义)允许大于8。因此,
char
int
都可以有32位,在这种情况下,
sizeof(int)==1
(和
char\u-BIT==32
)。+1:的确很有趣,但从技术上讲打破了不使用预处理器的要求。但是这个限制并不是为了否定这样好的答案:)好吧,如果你使用
#undef u8
函数,那么只有当你的程序有一个先前定义的名为
u8
(boooo)的宏时,预处理器的用法才是可见的。如果这是一个真正的问题,那么仍然可以使用特定于实现的push/pop宏pragmas/调用来解决(我相信大多数实现都有这些功能)。一个相当合理的论点是,在C++03系统上,可能有人定义u8来提供模拟的C++0x功能。尽管如此,我还是很喜欢这个答案。您可以将这个isCpp0x函数移动到一个单独的翻译单元,这样宏就不会影响其他代码。我认为使用预处理器依赖编译器设置一些宏值与使用预处理器检测实际的语言功能是有区别的。这就是为什么我认为这个答案是不作弊的。+ 1确实是一个很酷的想法:但是,在实践中,这将打破Visual C++ 2005/2088,它不支持C++ 0x,而是允许在模板中使用C++ +0x方式。我喜欢ADL虐待!然而,一个符合标准的C++03实现不能有一个名为
std::move
的函数吗?@fredwolflow:我不介意。用户界面糟透了!也许我应该把它翻过来
 int IsCxx03()
 {
   auto x = (int *)0;
   return ((int)(x+1) != 1);
}
#include <iostream>

const unsigned reallyIsCpp0x=1;
const unsigned isNotCpp0x=0;

template<unsigned>
struct isCpp0xImpl2
{
    typedef unsigned isNotCpp0x;
};

template<typename>
struct isCpp0xImpl
{
    static unsigned const reallyIsCpp0x=0x8000;
    static unsigned const isNotCpp0x=0;
};

bool isCpp0x() {
    unsigned const dummy=0x8000;
    return isCpp0xImpl<isCpp0xImpl2<dummy>>::reallyIsCpp0x > ::isNotCpp0x>::isNotCpp0x;
}

int main()
{
    std::cout<<isCpp0x()<<std::endl;
}
struct any
{
    template<typename T>
    any(T const&)
    {}
};

int move(any)
{
    return 42;
}

bool is_int(int const&)
{
    return true;
}

bool is_int(any)
{
    return false;
}


bool isCpp0x() {
    std::vector<int> v;
    return !is_int(move(v));
}
#define u8 "abc"

bool isCpp0x() {
   const std::string s = u8"def"; // Previously "abcdef", now "def"
   return s == "def";
}
template <class T> bool func(T&) {return true; } 
template <class T> bool func(...){return false;} 

bool isCpp0x() 
{
    int v = 1;
    return func<int&>(v); 
}
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);
}
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;
}
struct T
{
    bool flag;
    T() : flag(false) {}
    T(const T&) : flag(true) {}
};

std::vector<T> test(1);
bool is_cpp0x = !test[0].flag;
#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;
}