或多或少的标题暗示.虽然我还没有使用C++ 0x,但是我想在它发生时做好准备,而且我还想减少我必须重写的代码量才能使用它的一些功能.这样我就可以一次性地向前和向后兼容.
我发现的最有趣的一个是nullptr,我最近经常使用它.
在检查了"官方解决方法"和Meyer的建议之后,我决定在我的C++和未来的C++ 0x程序中使用它.第二部分很简单 - 作为关键字,nullptr只需支持.但第一部分让我感到有些不适.
Meyers提案的功能如下:
class nullptr_t { // ? this is my issue
// definition of nullptr_t
} nullptr = { };
Run Code Online (Sandbox Code Playgroud)
该提议的问题在于它声明了要声明为std::nullptr_tC++ 0x所需的类型.这意味着对于"感觉原生"的解决方法,必须通过重新打开std::命名空间来添加类型.我理解在C++程序中这是非法的(不像添加特殊化,这显然是皱眉和放开警告).
我想用nullptr在舒适和在C++程序合法的方式.我想到的一个选项是在另一个命名空间中声明类型然后使用它using:
namespace mylibrary {
class nullptr_t {
....
} nullptr = { };
// end namespace
}
// These would have to go in the header file.
using mylibrary::nullptr;
using …Run Code Online (Sandbox Code Playgroud) 如何在没有C++ 11的情况下检查对象是否为const std::is_const?据我所知,我不应该是const_cast一个声明为 const 的对象
请考虑以下标头和源文件:
// main.cpp
#include "myClass.h"
int main()
{
MyClass m;
m.foo<double>();
m.foo<float>();
}
Run Code Online (Sandbox Code Playgroud)
// myClass.h
#pragma once
#include <iostream>
using namespace std;
class MyClass
{
public:
template <typename T>
void foo()
{
cout << "Template function<T> called" << endl;
}
template <>
void foo<int>()
{
cout << "Template function<int> called" << endl;
}
template <>
void foo<float>();
};
Run Code Online (Sandbox Code Playgroud)
// myClass.cpp
#include "myClass.h"
template <>
void MyClass::foo<float>()
{
cout << "Template function<float> called" << endl;
}
Run Code Online (Sandbox Code Playgroud)
我得到了foo<float>专业化的链接错误.如果我将专门化的定义放在头文件中,那么一切都按预期工作.
我认为原因可能是该方法未被显式实例化(尽管完全特template …
我一直认为"奇异"迭代器是一个默认初始化的迭代器,它们可以作为类似的哨兵值:
typedef std::vector<Elem>::iterator I;
I start = I();
std::vector<Elem> container = foo();
for (I it = container.begin(), end = container.end(); it != end; ++it) {
if ((start == I()) && bar(it)) {
// Does something only the first time bar(it) is satisfied
// ...
start = it;
}
}
Run Code Online (Sandbox Code Playgroud)
但这个答案不仅表明我对"单数"的定义是错误的,而且我上面的比较完全是非法的.
是吗?
使用这个答案,我发明了自己的基于C++ 03模拟移动语义的方法swap.
首先,我检测移动语义(即C++ 03的可用性):
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || \
defined(_MSC_VER) && _MSC_VER >= 1600
#define HAS_MOVE_SEMANTICS 1
#elif defined(__clang)
#if __has_feature(cxx_rvalue_references)
#define HAS_MOVE_SEMANTICS 1
#else
#define HAS_MOVE_SEMANTICS 0
#endif
#else
#define HAS_MOVE_SEMANTICS 0
#endif
Run Code Online (Sandbox Code Playgroud)
然后我有条件地定义一个名为的宏move:
#if !HAS_MOVE_SEMANTICS
#include <algorithm>
namespace _cpp11_detail
{
template<bool B, class T = void> struct enable_if;
template<class T> struct enable_if<false, T> { };
template<class T> struct enable_if<true, T> { typedef T type; };
template<class T>
inline char …Run Code Online (Sandbox Code Playgroud) C++ 03标准是否保证足够小的非零整数完全表示double?如果没有,那么C++ 11呢?注意,我不是在这里假设IEEE合规性.
我怀疑答案是否定的,但我希望被证明是错的.
当我说足够小时,我的意思是,可以从C++ 03的保证中得到一些值,甚至可以通过可用的值来计算std::numeric_limits<double>.
编辑:
很明显(现在我已经检查过)std::numeric_limits<double>::digits与C++ 03和C++ 11 的情况相同DBL_MANT_DIG,并且std::numeric_limits<double>::digits10是相同的DBL_DIG.
更进一步,C++ 03遵循C90,而C++ 11在DBL_MANT_DIG和的意义上遵循C99 DBL_DIG.
C90和C99都声明最小允许值为DBL_DIG10,即10个十进制数字.
那么问题是,这是什么意思?这是否意味着保证最多10位十进制数的整数表示double?
在那种情况下,DECIMAL_DIGC99 的目的是什么,以及C99§5.2.4.2.2/ 12中的以下注释?
使用DECIMAL_DIG数字从(至少)double转换为十进制并且返回应该是标识函数.
以下是C99§5.2.4.2.2/ 9的含义DBL_DIG:
Number of decimal digits, 'q', such that any floating-point
number with 'q' decimal digits can be rounded into a
floating-point number with 'p' radix 'b' digits and back again
without …Run Code Online (Sandbox Code Playgroud) 我正在尝试从Crysis Wars SDK中的源代码构建DLL,并且在过去的Visual Studio早期版本(即2005年,2008年和2010年)上已经成功完成了.我的具体问题是:
Error 4 error LNK2019: unresolved external symbol "struct CTypeInfo const & __cdecl
TypeInfo<char>(char *)" (??$TypeInfo@D@@YAABUCTypeInfo@@PAD@Z) referenced in function
"void __cdecl SwapEndian<char>(char *,unsigned int)" (??$SwapEndian@D@@YAXPADI@Z)
G:\Noctis\Mods\Noctis\Code\GameCVars.obj GameDll
Run Code Online (Sandbox Code Playgroud)
我试图在Visual Studio中清理代码并在可能的情况下重建它,但这并没有改变任何东西.
我在这里遗漏了什么,或者从C++ 03到C++ 11有什么变化,这意味着如果没有恢复到旧版本的C++,这段代码就不再可编译了?
我已经在64位和32位上成功地在Visual Studio 2010上编译了此代码,因此它必须是与将项目迁移到Visual Studio 2015相关的一些问题.
在2012年,2013年和2015年版本的Visual Studio上进行编译会重现此错误,但不会重现2010年,因此似乎在C++ 11中引入了触发此问题的更改.
我究竟做错了什么?
阅读mem-fun的答案不是std的成员,它可能只是我需要包含一个标准库,我不需要在早期版本的Visual Studio中包含它.如果这是真的,我需要哪个库#include?
我也创建了一个GitHub的库只包含SDK中提供的原始未修改的代码,用于测试目的(在我自己做了一个错字,这似乎并没有在这里是如此的事件,但我在这里为把链接它可能会有所帮助).
如果重要,我在Windows 10 Professional x64上使用Visual Studio 2015企业版.
std::vector::push_back(constT& value)
Run Code Online (Sandbox Code Playgroud)
根据此要求类型T为CopyInsertable .
但是,除非我提供公共赋值运算符,否则使用failes(clang,GCC,Visual;两者都没有c ++ 11)编译以下程序.
#include <vector>
class A {
A& operator= (const A& rhs); //private !!
};
int main() {
std::vector<A> v;
A a;
v.push_back(a);
}
Run Code Online (Sandbox Code Playgroud)
为什么我需要提供这个赋值运算符,我的印象是复制结构就足够了.
PS我无法在标准中找到这个定义的位置,所以如果你能指出参考,我将非常感激
我们使用的外部库包含以下显式构造函数:
class Chart {
public:
explicit Chart(Chart::Type type, Object *parent);
// ...
};
Run Code Online (Sandbox Code Playgroud)
编译器抱怨以下警告:
chart.h: warning #2305: declaration of 'explicit' constructor
without a single argument is redundant
Run Code Online (Sandbox Code Playgroud)
是否二进制兼容只是删除explicitchart.h 中的关键字而不重新编译库以避免警告?我的感觉是它很安全,因为explicit在这种情况下无论如何都没有意义.谁能确认一下?
如何定义nullptr支持C++ 03和C++ 11?
下面的代码是用C++ 03和C++ 11编译编译的,而不改变C++ 11编译器中nullptr的含义吗?
#include <cstddef>
#if !defined(nullptr)
#define nullptr NULL
#endif
Run Code Online (Sandbox Code Playgroud)