防止函数接受const std :: string&接受0

问题描述 投票:0回答:1

一千个字:

#include<string>
#include<iostream>

class SayWhat {
    public:
    SayWhat& operator[](const std::string& s) {
        std::cout<<"here\n"; // To make sure we fail on function entry
        std::cout<<s<<"\n";
        return *this;
    }
};

int main() {
    SayWhat ohNo;
    // ohNo[1]; // Does not compile. Logic prevails.
    ohNo[0]; // you didn't! this compiles.
    return 0;
}

将数字0传递给接受字符串的方括号运算符时,编译器不会抱怨。相反,它会在通过以下方法进入方法之前编译并失败:

terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_S_construct null not valid

供参考:

> g++ -std=c++17 -O3 -Wall -Werror -pedantic test.cpp -o test && ./test
> g++ --version
gcc version 7.3.1 20180303 (Red Hat 7.3.1-5) (GCC)

我的猜测

编译器隐式使用std::string(0)构造函数输入该方法,由于没有充分的理由,会产生相同的问题(谷歌上述错误)。

问题

反正有在类方面解决此问题,因此API用户感觉不到这一点,并且在编译时检测到错误吗?

即添加重载

void operator[](size_t t) {
    throw std::runtime_error("don't");
}

不是一个好的解决方案。

一千个字:#include #include 类SayWhat {公共:SayWhat&运算符[](const std :: string&s){std :: cout <

c++ string std implicit-conversion
1个回答
0
投票

[问题是,std::string具有一个采用const char*的构造函数,这使0(即空指针)可以隐式转换为std::string

您可以将const char*标记为delete来标记过载。例如


0
投票

std::string(0)有效的原因是由于0是空指针常量。因此,它与采用指针的构造函数匹配。然后,它违反了一个前提条件,即不得将空指针传递给std::string。只有文字0会被解释为空指针常量,如果它是一个符文时间值,则不会出现此问题。

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