什么差异,如果有的话,C ++ 03和C ++ 11之间可以在运行时被检测到? [英] What differences, if any, between C++03 and C++11 can be detected at run-time?

查看:146
本文介绍了什么差异,如果有的话,C ++ 03和C ++ 11之间可以在运行时被检测到?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是可以编写一个函数,当使用C编译器编译将返回0,当与一个C ++编译器编译,将返回1(与琐碎sulution
的#ifdef __cplusplus 不感兴趣)。

例如:

  INT isCPP()
{
    返回的sizeof(char)的== sizeof的'C';
}

当然,上述方法仅当的sizeof(char)的是不一样的的sizeof(INT)

另外,更便携的解决方案是这样的:

  INT isCPP()
{
    的typedef诠释笔;
    {
       结构T
       {
           诠释一个[2];
       };
       返回的sizeof(T)==的sizeof(结构T);
    }
}

我不知道,如果例子是100%正确的,但你的想法。我相信还有其他方法来写同样的功能了。

什么差别,如果有的话,C ++ 03和C ++ 11之间可以在运行时检测到?换句话说,是有可能写出类似的功能这将返回指示是否是标准的C ++ 03编译器编译一个布尔值或C ++编译器11?

 布尔isCpp11()
{
    //?
}


解决方案

核心语言

使用访问枚举

 模板< INT>结构int_ {};模板< typename的T>布尔isCpp0xImpl(int_< T :: X  -  GT; *){返回true; }
模板< typename的T>布尔isCpp0xImpl(...){返回false; }枚举A {X};
布尔isCpp0x(){
  返回isCpp0xImpl< A>(0);
}

您也可以滥用新的关键字

 结构一个{};
结构B {一个A1,A2; };结构C:A {
  静态b constexpr(一());
};布尔isCpp0x(){
  返回(sizeof的Ç:: A())==的sizeof(B);
}

此外,事实上,字符串不要再转换为的char *

 布尔isCpp0xImpl(...){返回true; }
布尔isCpp0xImpl(字符*){返回false; }布尔isCpp0x(){返回isCpp0xImpl(); }

我不知道你是怎么可能对一个真正实现这个工作虽然。一个利用汽车

 结构X {X(INT Z = 0):Z(Z){} INT Z者除外; } Y(1);布尔isCpp0x(){
  自动X(Y);
  回报(y.z == 1);
}

以下是基于一个事实,即运营商INT和放大器;&安培; 是转换功能。 INT和放大器;&安培; C ++ 0x中,和转换到 INT 其次是逻辑和C ++ 03

 结构Ÿ{布尔X1,X2; };结构A {
  操作者INT();
  模板< typename的T>运营商T();
  布尔运算符+();
} 一个;Ÿ运营商+(BOOL,A);布尔isCpp0x(){
  返回的sizeof(安培; A ::运算INT和放大器;&功放+ A)==的sizeof(Y);
}

这测试用例不工作了的C ++ 0x的GCC(看起来像一个bug)和铛不起作用在C ++ 03模式。 一个铛PR已经提交

href=\"http://llvm.org/bugs/show_bug.cgi?id=9551\">修改的模板注入的类名称的治疗

 模板< typename的T>
布尔克(长){返回false; }模板<模板< typename的>类>
布尔克(INT){返回true; }模板< typename的T>
结构A {
  静态布尔的doIt(){
    返回G< A>(0);
  }
};布尔isCpp0x(){
  回到A<无效> :: doIt方法();
}


一对夫妇的检测这是否是C ++ 03或C ++ 0x中,可以用来证明重大更改。下面是一个扭捏的测试用例,它最初是用来证明这种变化,但现在是用来测试的C ++ 0x或C ++ 03。

 结构X {};
Ÿ结构{X X1,X2; };结构A {静态X B(INT); };
的typedef A B;结构C:A {
  使用:: B :: B: //(C ++ 0x中继承构造函数)
  静态Y B(...);
};布尔isCpp0x(){回报(sizeof的Ç:: B(0))==的sizeof(Y); }


标准库

检测缺乏运营商的void * C ++ 0x中的的std :: basic_ios

 结构,E {E(性病:: ostream的和放大器;){}};模板< typename的T>
布尔isCpp0xImpl(E,T){返回true; }
布尔isCpp0xImpl(无效*,INT){返回false; }布尔isCpp0x(){
  返回isCpp0xImpl(标准::法院,0);
}

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 #ifdef __cplusplus is not interesting).

For example:

int isCPP()
{
    return sizeof(char) == sizeof 'c';
}

Of course, the above will work only if sizeof (char) isn't the same as sizeof (int)

Another, more portable solution is something like this:

int isCPP()
{
    typedef int T;
    {
       struct T 
       {
           int a[2];
       };
       return sizeof(T) == sizeof(struct T);
    }
}

I am not sure if the examples are 100% correct, but you get the idea. I believe there are other ways to write the same function too.

What differences, if any, between C++03 and C++11 can be detected at run-time? In other words, is it possible to write a similar function which would return a boolean value indicating whether it is compiled by a conforming C++03 compiler or a C++11 compiler?

bool isCpp11()
{ 
    //???
} 

解决方案

Core Language

Accessing an enumerator using :::

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);
}

You can also abuse the new keywords

struct a { };
struct b { a a1, a2; };

struct c : a {
  static b constexpr (a());
};

bool isCpp0x() {
  return (sizeof c::a()) == sizeof(b);
}

Also, the fact that string literals do not anymore convert to char*

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

bool isCpp0x() { return isCpp0xImpl(""); }

I don't know how likely you are to have this working on a real implementation though. One that exploits auto

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

bool isCpp0x() {
  auto x(y);
  return (y.z == 1);
}

The following is based on the fact that operator int&& is a conversion function to int&& in C++0x, and a conversion to int followed by logical-and in C++03

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);
}

That test-case doesn't work for C++0x in GCC (looks like a bug) and doesn't work in C++03 mode for clang. A clang PR has been filed.

The modified treatment of injected class names of templates in C++11:

template<typename T>
bool g(long) { return false; }

template<template<typename> class>
bool g(int) { return true; }

template<typename T>
struct A {
  static bool doIt() {
    return g<A>(0);
  }
};

bool isCpp0x() {
  return A<void>::doIt();
}


A couple of "detect whether this is C++03 or C++0x" can be used to demonstrate breaking changes. The following is a tweaked testcase, which initially was used to demonstrate such a change, but now is used to test for C++0x or C++03.

struct X { };
struct Y { X x1, x2; };

struct A { static X B(int); };
typedef A B;

struct C : A {
  using ::B::B; // (inheriting constructor in c++0x)
  static Y B(...);
};

bool isCpp0x() { return (sizeof C::B(0)) == sizeof(Y); }


Standard Library

Detecting the lack of operator void* in C++0x' std::basic_ios

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);
}

这篇关于什么差异,如果有的话,C ++ 03和C ++ 11之间可以在运行时被检测到?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆