如何避免从整数0到指针的隐式转换,作为一个向量的元素。

问题描述 投票:9回答:3

有一种情况是,我想收集JSON中通往一个key的路径的所有节点名,考虑到数组索引的条件是 "0","1 "也可以,但容易忘记引号,导致在做dereference时崩溃。考虑到数组索引的条件 "0","1 "也是允许的,但很容易忘记引号,这将导致在做dereference时崩溃。所以我想拒绝这个条件。举个例子。

#include <vector>
#include <iostream>

int func(const std::vector<const char*>& pin) {
    return pin.size();
}

int main() {
    // {"aname", "3", "path", "0"} wanted but this still compile
    std::cout << func({"aname", "3", "path", 0}) << std::endl;
}

我发现并尝试了这个 如何避免对非构造函数进行隐式转换? 如以下。

#include <vector>
#include <iostream>

int func(const std::vector<const char*>& pin) {
    return pin.size();
}

template<typename T>
int func(T pin) = delete;

int main() {
    std::cout << func({"aname", "3", "path", 0}) << std::endl;
}

但编译器还是不明白我的意思。

有什么建议吗?术语和假设使用错误的地方请指出,谢谢!

c++ implicit-conversion function-parameter
3个回答
10
投票

类似这样的东西?和你建议的重载方案很相似,但是需要封装向量类型。如果你提供了一个字面意思,就会失败。0 因为选择了删除的构造函数重载。

#include <memory>
#include <new>
#include <vector>
#include <iostream>
using std::vector;

template<typename T>
struct no_zero {
        no_zero(T val) : val(val) {}
        no_zero(int val) = delete;
        operator T() { return val; }
        T val;
};

int func(const vector<no_zero<const char*> >& pin) {
    return pin.size();
}

int main() {
    // {"aname", "3", "path", "0"} wanted but this still compile
    std::cout << func({"aname", "3", "path", 0}) << std::endl;
}

4
投票

事后看来,C++中的许多隐式转换都是不幸的,这就是其中之一。

一个可以考虑的方案是 -Wzero-as-null-pointer-constant 在gcc和clang上。请小心,因为这将改变标准程序的行为,如果全局启用,可能会产生一些意想不到的效果。

g++ - 如何禁止从0到指针类型的隐式转换?

哪个Clang警告相当于GCC的Wzero-as-null-pointer-constant?


3
投票

我喜欢 Mikel Rychliski的回答. 然而,在以下方面已经存在一个解决方案 准则支持库:

gsl::not_null

我强烈推荐GSL。它是由许多C++专家创建和支持的,其中包括Bjarne Stroustrup本人和Herb Sutter。还有 C++核心指南 正在积极整合到编译器警告和静态分析器中。

© www.soinside.com 2019 - 2024. All rights reserved.