如何避免从int(0)到向量指针的隐式转换

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

[在某些情况下,我想收集JSON中键的路径的所有节点名称。考虑数组索引“ 0”,“ 1”的条件,也可以,但是很容易忘记引号,这在取消引用时会导致崩溃。所以我想拒绝这个。示例:

#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;
}

我发现并尝试了以下How do I avoid implicit conversions on non-constructing functions?

#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个回答
5
投票

这样的东西?它与您建议的重载解决方案非常相似,但需要包装向量类型。如果提供文字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;
}

3
投票

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

要考虑的一个选项是gcc和clang上的-Wzero-as-null-pointer-constant。请注意,因为这会更改标准程序的行为,并且如果在全局范围内启用它,可能会产生意想不到的影响。

g++ - how do I disable implicit conversion from 0 to pointer types?

Which Clang warning is equivalent to Wzero-as-null-pointer-constant from GCC?


1
投票

我喜欢Mikel Rychliski's answer。但是,Guideline Support Library中已经存在解决方案:

gsl::not_null

我强烈推荐GSL。它是由许多C ++专家(Bjarne Stroustrup本人和Herb Sutter)创建和支持的。并且gsl::not_null正在积极地集成到编译器警告和静态分析器中。

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