我想运行的功能:
struct foo;
void bar(const foo* p = 0);
Run Code Online (Sandbox Code Playgroud)
我如何调用函数:
auto thread = std::thread(&bar, NULL);
Run Code Online (Sandbox Code Playgroud)
警告:
foobar.h:223:9: 警告:将 NULL 传递给 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (*)(const foo*), _Args 的非指针参数 2 = {int}]' [-Wconversion-null]
我在这里缺少什么?
当我用非NULL参数调用函数时,警告消失了。
我试图理解为什么unique_ptr有一个nullptr_t构造函数
constexpr unique_ptr::unique_ptr( nullptr_t );
Run Code Online (Sandbox Code Playgroud)
我假设这是因为正常的一个参数构造函数是显式的,因此会拒绝nullptr值:
explicit unique_ptr::unique_ptr( pointer p );
Run Code Online (Sandbox Code Playgroud)
但是当我构建一个例子时,编译器很好:
namespace ThorsAnvil
{
template<typename T>
class SmartPointer
{
public:
SmartPointer() {}
explicit SmartPointer(T*){}
};
}
template<typename T>
using SP = ThorsAnvil::SmartPointer<T>;
int main()
{
SP<int> data1;
SP<int> data2(new int); // fine
SP<int> data3(nullptr); // fine
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
> g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.0.0
Thread model: posix
> g++ -Wall -Wextra -std=c++11 SP1.cpp
Run Code Online (Sandbox Code Playgroud)
为什么std :: …
请考虑以下代码:
#include <iostream>
template<typename T> // generic
void f(T)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
template<typename T> // overload for pointer types
void f(T*)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
int main()
{
int* p{nullptr};
f(p); // correct delegation to f<T*>();
f(nullptr); // calls f<T>();
}
Run Code Online (Sandbox Code Playgroud)
如您所见,调用f(nullptr)泛型f(T)中的结果,而不是指针重载f(T*).这很烦人.我知道为什么会发生这种情况:因为nullptr是类型std::nullptr_t,并且通用模板具有更高的过载等级.
如何以直截了当的方式"解决"这个问题?我当然可以写两个不同的实现,一个用于指针,一个用于nullptr_t,然后有一个通用的一个通过一些SFINAE发送到两个中的一个,但这看起来有点太复杂了.
假设我正在迭代一个数组,但超出了这个数组,因为我的循环很愚蠢。
如果内存中的对象直接位于与该数组相同类型的该数组之后,
检查可以array[invalid_index] == nullptr
保护我吗?
检查索引(大小未知)是否对 C 数组有效的正确方法是什么?
我遇到了一些代码问题,我需要通过多层函数传递指针.指针可以为null,因此我对nullptr的情况下的最终函数进行了重载.概念我有这样的事情:
void test_ptr(std::nullptr_t)
{
std::cout << "nullptr" << std::endl;
}
void test_ptr(double *d)
{
std::cout << *d << std::endl;
}
void test(double *d)
{
test_ptr(d);
}
int main()
{
test(nullptr);
}
Run Code Online (Sandbox Code Playgroud)
对我来说,理想的行为是,如果test调用第一个版本test_ptr,但事实并非如此.有没有机会操纵test它以便称之为"正确"的版本?
我有以下函数,它最初对函数参数执行一些验证.
char *doSomething(const char* first, const char* second) {
if((first == nullptr || *first == '\0') && (second == nullptr || *second == '\0')) {
return nullptr;
} else if (first == nullptr || *first == '\0') {
return (char *) second;
} else if (second == nullptr || *second == '\0') {
return (char *) first;
}
//doSomething
}
Run Code Online (Sandbox Code Playgroud)
强制转换函数参数是否返回一个char*指向内存中不同区域的新参数?我不想允许使用此函数的人操纵常量参数指向的值.我希望char*返回一个new ,其值与其中一个参数相同(如果是nullptr或者为空).
跟进:布尔变量会更好吗?我意识到我正在对每个变量执行两次相同的检查,但我不会在此函数的代码中的任何其他位置使用此布尔值.
我是C++的新手,正在尝试学习指针的概念.有人能告诉我为什么下面的C++声明是非法的吗?在我看来,这是合法的,但我被告知它是非法的.
int null = 0, *p = null;
Run Code Online (Sandbox Code Playgroud) 问题是,对具有多重继承的类的第二个超类的nullptr的隐式转换(至少在LLVM 7.0.2中)在调整中应用于nullptr.指针现在不再为null(如果在超类的方法中执行空检查)可能导致崩溃(我猜技术上是未定义的行为).
这是一个最小的例子:
#include <iostream>
inline bool pointerIsNotNull(const void* ptr) { return ptr != nullptr; }
class IntValue {
public:
IntValue() { }
int getIntValue() { return pointerIsNotNull(this) ? value : 0; }
private:
int value;
};
static const char* nullptrChar = "nullptr";
class CharValue {
public:
CharValue() { }
const char* getCharValue() { return pointerIsNotNull(this) ? value : nullptrChar; }
private:
char* value;
};
class Foo : public IntValue, public CharValue {
public:
Foo() { }
double getDoubleValue() { …Run Code Online (Sandbox Code Playgroud) C++ 03标准说:
5.3.5删除
[...]在任一替代方案中,如果delete的操作数的值是空指针,则操作无效.[...]
char *p = nullptr;
delete p; //no effect
Run Code Online (Sandbox Code Playgroud)
这意味着,在c ++中删除空指针是有效的.
关于在nullptr指针上调用delete的C++ 17标准是什么意思?
在我使用C++的早期,我似乎记得你可以使用NULL指针调用成员函数,并在成员函数中检查它:
class Thing {public: void x();}
void Thing::x()
{ if (this == NULL) return; //nothing to do
...do stuff...
}
Thing* p = NULL; //nullptr these days, of course
p->x(); //no crash
Run Code Online (Sandbox Code Playgroud)
这样做可能看起来很愚蠢,但是当编写递归函数来遍历数据结构时,这绝对是很棒的,导航很容易进入NULL的盲道; 导航功能可以在顶部对NULL进行单一检查,然后轻松地调用自己尝试深入导航而不会乱丢代码并进行额外检查.
至少根据g ++,自由(如果它曾经存在)已被撤销.编译器警告它,如果编译优化,它会导致崩溃.
问题1:C++标准(任何风格)是否禁止使用NULL?或者g ++只是在我面前?
问题2.更哲学,为什么?'这'只是另一个指针.指针的荣耀在于它们可以是nullptr,这是一个有用的条件.
我知道我可以通过创建静态函数来解决这个问题,将第一个参数传递给数据结构的指针(hellllo Days of C),然后检查指针.我很惊讶我需要.
编辑:为了提出答案,我希望看到关于为什么不允许这样做的标准的章节和经文.请注意,我在NO POINT处的示例取消引用NULL.这里没有什么是虚拟的,并且p被复制到"参数this"但在使用之前被检查.没有任何差别!因此,取消引用NULL不能用作UB的声明.
人们对*p做出了下意识的反应,并假设如果p为NULL则无效.但确实如此,证据就在这里:http: //www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232 事实上,当一个指针p令人惊讶时,它会调出两个案例有效为*p:当p为null或p指向一个元素超过数组末尾时.你必须做的就是使用*p的值......除了获取它的地址.&*p其中p == nullptr表示任何指针类型p都有效.可以指出p-> x()实际上是(*p).x(),但在一天结束时转换为x(&*p)并且形成得非常好且有效.对于p = nullptr ...它只是变成x(nullptr).
我认为我的辩论应该与标准界有关; 他们急于削弱空引用的概念,他们的措辞不清楚.因为这里没有人要求p-> x()是UB而不试图要求它是UB,因为*p是UB; 并且因为*p绝对不是UB,因为x()的任何方面都没有使用引用的值,我将把它归结为g ++对标准歧义的超越.使用静态函数和额外参数的绝对相同的机制已经很好地定义了,所以它不会停止我的重构工作.考虑撤回的问题; 可移植代码不能假设这个== nullptr会工作但是有一个可移植的解决方案,所以最后它没关系.