【问题标题】:skipping adding constructors when inheriting from std::string class从 std::string 类继承时跳过添加构造函数
【发布时间】:2015-05-16 23:41:08
【问题描述】:

尝试对 std::string 进行参数化,以便它支持方法“bool operator==(int)”。我遇到了错误:

$ g++ -std=c++11 te2.cc
te2.cc: In function ‘int main(int, char**)’:
te2.cc:20:20: error: no matching function for call to ‘mstring::mstring(const char [4])’
te2.cc:20:20: note: candidates are:
te2.cc:10:7: note: mstring::mstring()
te2.cc:10:7: note:   candidate expects 0 arguments, 1 provided
te2.cc:10:7: note: mstring::mstring(const mstring&)
te2.cc:10:7: note:   no known conversion for argument 1 from ‘const char [4]’ to ‘const mstring&’
te2.cc:10:7: note: mstring::mstring(mstring&&)
te2.cc:10:7: note:   no known conversion for argument 1 from ‘const char [4]’ to ‘mstring&&’

这里是简单的来源:

#include <unordered_map>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <iostream>

using namespace std;


class mstring : public string {
public:
    //mstring (char* p) : std::string(p) {};
    bool operator == (int x) {
        int n = atoi(this->c_str());
        return (n == x);
    }
};

int main(int argc, char *argv[])
{
    mstring t("123");
    if (t == atoi(argv[1])) {
        printf("yes\n");
    } else {
        printf("no\n");
    }
}

如果我取消注释构造函数/mstring (char* p) : std::string(p) {};,那么它编译并运行良好。

问题是,如果可以在不为 mstring 定义构造函数的情况下使其工作,只需使用基类的构造函数(反正没有新的数据成员)?谢谢。

【问题讨论】:

  • 通常从std 命名空间继承类是一个非常糟糕的主意。
  • 如果您愿意,可以将operator==(const std::string&amp;, int) 定义为独立的非成员函数。事实上,您可能想要这样 - 您可能还想要一个对称的 operator==(int, const std::string&amp;),它无论如何都不能是成员函数。
  • 您不需要将 argv[1] 转换为 int。直接将其与 std::string 进行比较。

标签: c++ c++11


【解决方案1】:

如果提供一个独立的运算符函数而不是从std::string 继承(这使得该代码总体上更可用):

bool operator==(const std::string& s, int i) {
    int n = atoi(s.c_str());
    return (n == i);
}

bool operator==(int i, const std::string& s) {
    return s == i;
}

或者更通用:

template<typename T>
bool operator==(const std::string& s, T t) {
    std::istringstream iss;
    iss << t;
    return (s == iss.str());
}

std 命名空间中的类不打算被继承,而只是用于接口和函数参数。从这些类继承会降低您的代码的可用性,因为客户端需要使用您的实现,而不仅仅是使用 std 类型。


另请注意:对于您的特定用例,根本不需要转换任何内容,除非您想断言 argv[1] 包含一个数字(其中 atoi() 肯定不是最好的方法,请查阅stoi() 代替)。您可以只比较字符串:

if (std::string("123") == argv[1]) {
    printf("yes\n");
} else {
    printf("no\n");
}

【讨论】:

  • 这是完美的解决方案。以前见过,但直到我看到你的解决方案才想到。谢谢。
【解决方案2】:

您可以通过添加显式继承构造函数

using string::string;

在你的班级

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 2015-05-25
    • 1970-01-01
    • 2018-06-06
    相关资源
    最近更新 更多