首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >通用模板ostream <<操作符的C++模糊重载

通用模板ostream <<操作符的C++模糊重载
EN

Stack Overflow用户
提问于 2015-05-29 13:54:17
回答 1查看 489关注 0票数 4

这个问题遵循我之前的问题:Generic operator<< ostream C++ for stringifiable class,在这里,我希望实现一个泛型<<ostream操作符,它将对拥有to_str()方法的任何类工作。

由于这个to_str(),我成功地检查了类是否实现了std::cout << stringify(a)方法并使用了answer。然而,我在编写模板ostream<<操作符使std::cout << a工作时遇到了困难。

以下测试代码:

代码语言:javascript
运行
复制
#include <iostream>
#include <sstream>
#include <string>

template<class ...> using void_t = void;

template<typename T, typename = void>
struct has_to_string
: std::false_type { };

template<typename T>
struct has_to_string<T, 
    void_t<decltype(std::declval<T>().to_str())>
    >
: std::true_type { };

template<typename T> std::enable_if_t<has_to_string<T>::value, std::string> 
stringify(T t) { 
    return t.to_str(); 
} 

template<typename T> std::enable_if_t<!has_to_string<T>::value, std::string> 
stringify(T t) { 
    return static_cast<std::ostringstream&>(std::ostringstream() << t).str(); 
} 

// The following does not work
/*
template<typename T> std::enable_if_t<has_to_string<T>::value, std::ostream&> 
operator<<(std::ostream& os, const T& t) {
    os << t.to_str();
    return os;
}

template<typename T> std::enable_if_t<!has_to_string<T>::value, std::ostream&> 
operator<<(std::ostream& os, const T& t) {
    os << t;
    return os;
}
*/

struct A {
    int a;
    std::string to_str() const { return std::to_string(a); }
};

struct B {
    std::string b;
    std::string to_str() const { return b; }
};

int main() {
    A a{3};
    B b{"hello"};
    std::cout << stringify(a) << stringify(b) << std::endl;    // This works but I don't want to use stringify
    // std::cout << a << b << std::endl;               // I want this but it does not work
}

给出与原始问题相同的错误。我做错什么了?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-29 15:50:53

当类型为std::operator<<时,您会得到“operator<<错误”的模糊重载,因为您的代码中的模板版本具有与ostream标头中提供的版本相同的优先级。

您可以通过使用以下内容更改测试程序来检查这是问题的根源:

代码语言:javascript
运行
复制
int main() {
    std::cout << std::string("There is your problem") << std::endl;
}

你仍然会看到同样的错误。

为了解决这个问题,您可以添加一个operator<<的显式定义,它将优先于两个相互冲突的模板。

代码语言:javascript
运行
复制
std::ostream& operator<<(std::ostream& os, const std::string& t) {
    using std::operator<<;
    os << t;
    return os;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30531429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档