可以编写一个函数,当用C编译器编译时它将返回0,并且当用C++编译器编译时,将返回1(微不足道的
#ifdef __cplusplus情况并不令人感兴趣).
例如:
int isCPP()
{
return sizeof(char) == sizeof 'c';
}
Run Code Online (Sandbox Code Playgroud)
当然,只有在sizeof (char)不相同的情况下才会起作用sizeof (int)
另一个更便携的解决方案是这样的:
int isCPP()
{
typedef int T;
{
struct T
{
int a[2];
};
return sizeof(T) == sizeof(struct T);
}
}
Run Code Online (Sandbox Code Playgroud)
我不确定这些例子是否100%正确,但你明白了.我相信还有其他方法可以编写相同的功能.
在运行时可以检测到C++ 03和C++ 11之间有什么区别?换句话说,是否有可能编写一个类似的函数,它返回一个布尔值,表明它是由符合标准的C++ 03编译器还是C++ 11编译器编译的?
bool isCpp11()
{
//???
}
Run Code Online (Sandbox Code Playgroud) 的C++ 0x将会使下面的代码和类似代码形成不良的,因为它需要一个所谓的收缩转换的double一个int.
int a[] = { 1.0 };
Run Code Online (Sandbox Code Playgroud)
我想知道这种初始化是否在现实代码中被大量使用.这个改变将破坏多少代码?如果您的代码受到影响,是否需要在代码中修复此问题?
供参考,参见n3225的8.5.4/6
缩小转换是隐式转换
- 从浮点类型到整数类型,或
- 从long double到double或float,或从double到float,除非source是常量表达式,转换后的实际值在可以表示的值范围内(即使它不能精确表示),或者
- 从整数类型或无范围枚举类型到浮点类型,除非源是常量表达式,转换后的实际值将适合目标类型,并在转换回原始类型时生成原始值,或者
- 从整数类型或未范围的枚举类型到不能表示原始类型的所有值的整数类型,除非source是常量表达式,并且转换后的实际值将适合目标类型并且将在生成原始值时生成原始值转换回原始类型.
介绍
随着C++ 14(又名C++ 1y)标准处于接近最终的状态,程序员必须问自己有关向后兼容性以及与此相关的问题.
这个问题
在该问题的答案中,指出该标准有一个附录,专门用于有关修订之间变化的信息.
如果可以解释前面提到的附录中的这些潜在问题,或许在任何与那里提到的相关的正式文件的帮助下,将会有所帮助.
我今天跑了一个非常微妙的问题我希望得到你的意见.
考虑以下花园式共享体成语类:
struct S
{
S() : p_impl(new impl) {}
private:
struct impl;
boost::shared_ptr<impl> p_impl;
};
Run Code Online (Sandbox Code Playgroud)
当您尝试以下列方式将它们放入向量时,会出现这种乐趣:
std::vector<S> v(42);
Run Code Online (Sandbox Code Playgroud)
现在,至少使用MSVC 8,所有元素v共享同一个impl成员.实际上,导致这种情况的原因是vector构造函数:
template <typename T, typename A = ...>
class vector
{
vector(size_t n, const T& x = T(), const A& a = A());
...
};
Run Code Online (Sandbox Code Playgroud)
在这些场景中,只有一个S对象被默认构造,从中复制了它们的n元素vector.
现在,使用C++ 11,有rvalue引用.所以它不能像这样工作.如果a vector被构造为
std::vector<S> v(42);
Run Code Online (Sandbox Code Playgroud)
然后很可能,实现将选择默认构造n向量内的对象,因为复制构造可能不可用.在这种情况下,这将是一个突破性的变化.
我的问题是:
std::vector必须具有如上定义的构造函数,即.使用默认参数?特别是保证向量对象的条目被复制而不是默认构造?PS:请不要评论 …
目前,使用g ++ - 4.8.1,您必须通过C++ 11模式编译文件
g++ -std=c++11 -o prog.x prog.cpp
Run Code Online (Sandbox Code Playgroud)
我可以说,是否有计划?
g++ -o prog.x prog.cpp
Run Code Online (Sandbox Code Playgroud)
编译prog.cpp?
也许prog.cpp有
#include <regex>thread_localclass Widget { int member = 5; }MyType operator"" myt(const char*, sze_t);取自:cppreference
直到C++ 11:
如果提取失败(例如,如果输入了预期数字的字母),则值保持不变,并设置failbit.
从C++ 11开始:
如果提取失败,则将零写入值并设置failbit.如果提取导致值太大或太小而无法拟合值,
std::numeric_limits<T>::max()或者std::numeric_limits<T>::min()被写入并且设置了failbit标志.
由于此更改,这意味着以下代码段:
int x = 1;
std::cin >> x;
return x;
Run Code Online (Sandbox Code Playgroud)
如果数值转换失败,将1在C++ 11之前返回,0否则返回.
为什么标准委员会会引入如此微妙的突破性变化?或者更确切地说,在C++ 11之前可以使用哪种代码来保证这种变化?
我知道默认情况下不应该启用编程语言的实验性功能,所以我欢迎使用标志-std=c++0x和-std=c++1y.但是,C++ 11现在已经成为标准.为什么编译器仍需要-std=c++11启用对其功能的支持?
在Rvalue References简介中,forward定义如下:
template <typename T>
struct identity { typedef T type; };
template <typename T>
T &&forward(typename identity<T>::type &&a) { return a; }
Run Code Online (Sandbox Code Playgroud)
identity班级的目的是什么?为什么不:
template <typename T>
T &&forward(T &&a) { return a; }
Run Code Online (Sandbox Code Playgroud) 似乎clang(3.4)自动接受一些c ++ 11(例如auto,for(:))而没有特殊标志(虽然产生警告),但不是其他部分(例如lambdas).
例如,以下编译clang++ c++11.success.cpp:
#include <vector>
int main( int argCount, char ** argVec )
{
std::vector<int> vec;
for( auto & item : vec )
{
++item;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但这失败了clang++ c++11.failure.cpp:
#include <vector>
int main( int argCount, char ** argVec )
{
std::vector<int> vec;
auto lambda = [] ( int & foo ) { return ++foo; }; //This line fails at []
for( auto & item : vec )
{ …Run Code Online (Sandbox Code Playgroud)