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


9

在某些情况下,我想收集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;
}

我发现并尝试过该如何避免在非构造函数上进行隐式转换?如下:

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

但是编译器仍然不了解我。

有什么建议吗?
请指出对术语和假设的任何滥用,谢谢!


为什么使用std::vector<const char*>而不是std::vector<std::string>>
bolov

你也想禁止nullptr吗?
Jarod42

@bolov首先,我考虑将这些节点名称传递给JSON分析接口,该接口使用C样式的char *作为输入,但这并不限于此。我已经测试过,使用std :: vector <std :: string >>在编译时仍然接受0,但是在运行时崩溃,在我的机器上GCC报告“ basic_string :: _ M_construct null无效”。
rustyhu

@ Jarod42是的,想要的是C样式的字符串文字。
rustyhu

Answers:


9

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.