根据标准N4713(7.11/1)的草案:
空指针常量是一个整数文字(5.13.2),其值为零或prvalue类型
std::nullptr_t.
和21.2.3/2:
宏
NULL是一个实现定义的空指针常量.
以下NULL可以定义为nullptr.cppreference上提到了相同的内容:
#define NULL 0
//since C++11
#define NULL nullptr
Run Code Online (Sandbox Code Playgroud)
同时"Additive operators"条款说(8.5.6/7):
如果将值
0添加到空指针值或从空指针值中减去该值,则结果为空指针值.如果减去两个空指针值,则结果将等于0转换为该类型的值std::ptrdiff_t.
因此,以下代码应该是有效的:
0 + nullptr;
nullptr - nullptr;
Run Code Online (Sandbox Code Playgroud)
但由于缺乏+/-运营商对于std::nullptr_t该代码是无效的.
有没有我没有考虑到的东西或NULL宏不能实际定义为nullptr?
考虑以下代码:
int main() {
int (*p)[]; // pointer to array with unspecified bounds
int a[] = {1};
int b[] = {1,2};
p = &a; // works in C but not in C++
p = &b; // works in C but not in C++
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在纯C中,您可以指定指向任何维度的数组的此类地址的指针.但是在C++中你不能.我发现编译器允许为这样的指针赋值的一种情况:
struct C
{
static int v[];
};
int main()
{
int (*p)[] = &C::v; // works in C++ if 'v' isn't defined (only declared)
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但找不到此代码的任何有用案例.
任何人都可以给出一个有用的示例(在C++中)指向具有未指定边界的数组的指针吗?或者只剩下来自C的遗迹?
std::mem_fun和之间有什么区别std::mem_fn?为什么命名如此令人困惑?
Boost的文档说在大多数情况下std::mem_fn都可以替代std::mem_fun.那你在什么情况下仍会使用std::mem_fun?
我安装了gcc 4.9.2.我使用以下命令编译了程序:
/root/gcc-4.9.2/bin/g++ -std=c++1y testing.cpp
Run Code Online (Sandbox Code Playgroud)
请注意,除了该选项-std=c++1y,还有另一个选项-std=c++14.编译器是否以相同的方式工作并为两个选项生成完全相同的可执行文件?
我尝试使用C++ 17标准.我试图使用C++ 17的一个功能if constexpr.我有一个问题...请看下面的代码.这编译没有错误.在下面的代码中,我试图用if constexpr它来检查它是否是一个指针.
#include <iostream>
#include <type_traits>
template <typename T>
void print(T value)
{
if constexpr (std::is_pointer_v<decltype(value)>)
std::cout << "Ptr to " << *value << std::endl; // Ok
else
std::cout << "Ref to " << value << std::endl;
}
int main()
{
auto n = 1000;
print(n);
print(&n);
}
Run Code Online (Sandbox Code Playgroud)
但是,当我重写上面的代码,如下所示,其中,if constexpr在main功能:
#include <iostream>
#include <type_traits>
int main()
{
auto value = 100;
if constexpr (std::is_pointer_v<decltype(value)>)
std::cout << "Ptr to " …Run Code Online (Sandbox Code Playgroud) 根据C ++草案expr.add,当您减去相同类型但不属于同一数组的指针时,其行为是不确定的(强调是我的):
当两个指针表达式P和Q相减时,结果的类型为实现定义的有符号整数类型;此类型应与在标头([support.types])中定义为std :: ptrdiff_t的类型相同。
- 如果P和Q都得出空指针值,则结果为0。(5.2)
否则,如果P和Q分别指向同一数组对象x的元素x [i]和x [j],则表达式P-Q具有值i?j。
否则,行为是不确定的。 [?注意:如果值i?j不在std :: ptrdiff_t类型的可表示值的范围内,则行为是不确定的。-?尾注?]
将此类行为设为未定义(而不是由实现定义)的原理是什么?
C++ 14通过0b为值键入prefix来增加使用二进制文字的能力:
int v = 0b1111; // 15 in decimal
Run Code Online (Sandbox Code Playgroud)
但是没有std::bin类似std::hex或者流的操纵器std::oct.所以我需要std::bitset用于打印目的:
std::cout << std::bitset<4>(v) << "\n";
Run Code Online (Sandbox Code Playgroud)
是否已提出或考虑过?如果是这样,这个想法的现状是什么?
C++允许在一个名称空间中使用具有相同名称的类和函数:
struct S {};
void S() {}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,纯名称S意味着功能S.要使用struct,您需要struct在name之前显式添加.
它也可以制作功能模板并仍然使用它们:
template <class T>
void S() {}
struct S {};
Run Code Online (Sandbox Code Playgroud)
但禁止使用模板结构
void S() {}
template <class T>
struct S {};
Run Code Online (Sandbox Code Playgroud)
并给出如下错误:
Run Code Online (Sandbox Code Playgroud)error: redefinition of 'S' as different kind of symbol
这是什么原因?为什么不允许在这里使用模板结构?是否有一个地方使用明确的关键字任何情况struct之前S(如非模板版本)没能解决命名冲突,如果它被允许?也许存在提案?
根据这些指导方针:
如果需要默认析构函数,但其生成已被抑制(例如,通过定义移动构造函数),请使用
=default.
我无法想象,如果没有具有移动构造函数的类中的显式默认析构函数,代码将会格式错误.
有人可以告诉我上面的例子确认报价吗?
struct S {
S() {};
S( S&& ) {}; // move ctor
};
int main() {
S s; // there is no need to declare dtor explicitly =default
}
Run Code Online (Sandbox Code Playgroud) 关于评估顺序的主题说,在C++ 17之前,以下代码会导致未定义的行为:
a[i] = i++;
Run Code Online (Sandbox Code Playgroud)
这是由于在评估赋值表达式的左右部分时未指定的顺序而发生的.
C++ 14标准1.9/15说:
如果对标量对象的副作用相对于同一标量对象的另一个副作用或使用相同标量对象的值进行的值计算未被排序,并且它们不可能是并发的(1.10),则行为未定义.
但是如果我们使用std::vector它的iterator对象而不是标量对象i呢?
std::vector<int> v = {1, 2};
auto it = v.begin();
*it = *it++; // UB?
Run Code Online (Sandbox Code Playgroud)
是否存在未定义的行为(直到c ++ 17)?
c++ ×10
c++11 ×3
c++14 ×3
arrays ×1
binary ×1
c++17 ×1
destructor ×1
gcc ×1
if-constexpr ×1
null ×1
nullptr ×1
overloading ×1
pointers ×1
std ×1
templates ×1