【问题标题】:Use of overloaded operator ambiguous重载运算符的使用不明确
【发布时间】:2016-12-20 12:31:55
【问题描述】:

以下代码:

typedef void HELPER;

const HELPER* helper = _helper;

inline ostream& operator <<(ostream& out,  const HELPER* arg) 
{ out << (const char*)(arg); return out; }

如果我尝试了就会爆炸

cout << helper;

具体来说,我得到:

main.cpp:35:28:错误:使用重载运算符“”和“const HELPER *”(又名“const void *”))

它列出了一些候选人:

/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/ostream:207:0: note: candidate function
    basic_ostream& operator<<(const void* __p);
                   ^
main.cpp:25:17: note: candidate function
inline ostream& operator <<(ostream& out,  const HELPER* arg) 
                ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/ostream:195:20: note: candidate function
    basic_ostream& operator<<(bool __n);
                   ^

我有点惊讶我的 typedef 没有在这里调用更强的类型匹配。我怎样才能让这个运算符重载运行?

编辑:进一步澄清,这段代码的目的是我双重定位一组 Arduino 库。他们经常通过以下方式管理他们的字符串:

typedef void __FlashStringHelper;

void showHelp(const __FlashStringHelper* helpText)
{
   Serial.print(helpText);
}

我喜欢 iostream 并计划在这个双重目标上,所以我在 Serial 对象上重载

#define cout Serial

void showHelp(const __FlashStringHelper* helpText)
{
   cout << helpText;
}

现在我想将真正的 iostream 实际定位为不同的拱门,但旧的 Arduino 代码与其 __FlashStringHelpers 没有太大的不同。这就是我所在的地方

【问题讨论】:

  • 您的符号HELPER 基本上只是void别名。因此,const void*(您的和标准的)有两个重载,而且指针可以隐式转换为 bool,从而为您提供第三种选择。
  • typedef 没有引入新类型。
  • 您希望通过显示的解决方案解决的实际问题是什么?你为什么做了这样的超载?它的目的是什么?也许我们可以帮你解决这个问题?请参阅有关the XY problem 的一些相关阅读。
  • 谢谢大家,它现在可以工作了!

标签: c++ operator-overloading


【解决方案1】:

typedef 不会创建类型,而是为其设置别名,

inline ostream& operator <<(ostream& out,  const HELPER* arg) 

等价于

inline ostream& operator <<(ostream& out,  const void* arg)

也许你想创建一个名为 HELPER 的类型

class HELPER{};

【讨论】:

  • 可能还想提一下,你不能重载内置类型
  • operatormsdn.microsoft.com/en-us/library/1z2f6c2k.aspx
【解决方案2】:

Zekian 回答了您的问题,这可能对您有用或帮助您实现您想要做的事情。

#include <iostream>

template <class T>
class Helper {
private:
    T obj_;

public:
    explicit Helper<T>( T obj ) : obj_(obj) {}

public:
    T getObj() const { return obj_; }
    void setObj( T obj ) { obj_ = obj; }        

    template<class U>
    inline friend std::ostream& operator<< ( std::ostream& out, const Helper<U>& rhs ); 
};

template<class U>
std::ostream& operator<< ( std::ostream& out, const Helper<U>& rhs ) {
    return out << rhs.obj_;
}

int main() {
    Helper<int> helper( 3 );
    std::cout << helper << std::endl;
    return 0;
}

它是一个带有重载 ostream 运算符

示例 - 相同的类模板,但这次使用的是类或结构。

#include <iostream>

template <class T>
class Helper {
private:
    T obj_;

public:
    explicit Helper<T>( T obj ) : obj_(obj) {}

public:
    T getObj() const { return obj_; }
    void setObj( T obj ) { obj_ = obj; }

    template<class U>
    inline friend std::ostream& operator<< ( std::ostream& out, const Helper<U>& rhs ); 
};

template<class U>
std::ostream& operator<< ( std::ostream& out, const Helper<U>& rhs ) {
    return out << rhs.obj_;
}

struct Staff {
    int employees = 4; // Default to 4
};

int main() {
    Staff staff; 
    Helper<Staff> helper( staff );
    std::cout << helper << std::endl; // will not compile

    return 0;
}

要修复这个 ostream,需要一个重载的 Staff 对象操作符

template <class T>
class Helper {
private:
    T obj_;

public:
    explicit Helper<T>( T obj ) : obj_(obj) {}

public:
    T getObj() const { return obj_; }
    void setObj( T obj ) { obj_ = obj; }

    template<class U>
    inline friend std::ostream& operator<< ( std::ostream& out, const Helper<U>& rhs );
};

template<class U>
std::ostream& operator<< ( std::ostream& out, const Helper<U>& rhs ) {
    return out << rhs.obj_;
}

struct Staff {
    int employees = 4;

    inline friend std::ostream& operator<< ( std::ostream& out, const Staff& rhs );
};

std::ostream& operator<<( std::ostream& out, const Staff& rhs ) {
    return out << rhs.employees;
}

int main() {

    Staff staff;
    Helper<Staff> helper( staff );   // Default to 4
    std::cout << helper << std::endl; // Will Print 4
    // To Change Staff's Employee count for the helper wrapper do this:
    staff.employees = 12; // Change To 12
    helper.setObj( staff ); // pass the changed struct back into helper
    std::cout << helper3 << std::endl; // Will Now Print 12

    // And For Other Default Types
    Helper<int> helper2( 3 );
    std::cout << helper2 << std::endl;

    Helper<float> helper3( 2.4f );
    std::cout << helper3 << std::endl;

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多