什么差异,如果有的话,C ++ 03和C ++ 11之间可以在运行时被检测到? [英] What differences, if any, between C++03 and C++11 can be detected at run-time?
问题描述
这是可以编写一个函数,当使用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屋!