C++ 容器-如果为类型定义了运算符<<,则列出成员?

标签 c++ c++11

如果这是重复的,我很抱歉,我不太确定我在找什么。

我定义了一个:

template<class T>
::std::ostream& operator<<(::std::ostream& stream,const container<T>& list);

它只能说“长度的容器”(或其他东西) 如果这可以列出容器的内容,那就太好了,如果

::std::ostream& operator<<(::std::ostream& stream, const T&);

被定义。然而,它可能并不总是被声明。这是编译时已知的东西(假设编译器可以看到声明,用户错误可能意味着它永远不会被包含)

这可以做到吗?

这肯定是重复的,我不是第一个想要这样做的人,但我不确定我要搜索什么。

如果有任何方法可以做到这一点,我们将不胜感激。

注意:

我确实考虑过使用特征但是(复制并粘贴我的评论):

s there a C++11 way? I thought about traits too but you can't give int a trait, assuming false by default (unless a trait exists and is true) is great, but you can't do primitive types, or types defined from libraries, you can of course create an operator<< for them

示例

想象一下:

container<int> someints(10); /*10 ints*/
container<A> someAs(5); /*5 As*/
container<B> someBs(7); /*7 Bs*/

与:

/*Obviously << for ints is defined*/

ostream& operator<<(ostream& stream, const B& b) {
    stream<<"Whatever a B wants to do";
    return stream;
}

template<class T>
ostream& operator<<(ostream& stream, const container<T>& list) {
    stream<<"A list of length "<<list.get_length();
    /*magic - if there is a << for T*/
    stream<<"\n";
    for(int k=0;k!=list.get_length();k++) {
        stream<<list[k]<<"\n";
    }
    /*end of magic*/
    return stream;
}

然后:

cout<<someints; /*shows a list of ints*/
cout<<someAs; /*shows its a list of 5 things - but cannot list the contents obviously*/
cout<<someBs; /*Showws it's a list of 7 things - and like someints lists them*/

最佳答案

这可以做到:你可以使用 std::enable_if<...>使用输出运算符根据谓词选择应使用哪个版本的代码。下面是一个演示。功能测试有点难看,但现在我不知道如何真正改进它。参见 here一个活生生的例子。

#include <iostream>
#include <type_traits>

template <typename T>
struct container
{
    container(T const& v): value(v) {}
    T value;
};

template <typename T>
struct has_output_test {
    template <typename S>
    static std::true_type test(typename std::decay<decltype(
        std::declval<std::ostream&>() << std::declval<S>())>::type*);
    template <typename S>
    static std::false_type test(void*, ...);
};

template <typename T>
struct has_output
    : decltype(has_output_test<T>::template test<T>(
                    static_cast<std::ostream*>(0)))
{
};

template <typename T>
typename std::enable_if<has_output<T>::value, std::ostream&>::type
operator << (std::ostream& out, container<T> const& c)
{
    return out << "container[" << c.value << "]";
}

template <typename T>
typename std::enable_if<!has_output<T>::value, std::ostream&>::type
operator << (std::ostream& out, container<T> const&)
{
    return out << "container[unknown]";
}

struct foo {};

int main()
{
    std::cout << "foo=" << container<foo>(foo()) << '\n';
    std::cout << "int=" << container<int>(int()) << '\n';
}

关于C++ 容器-如果为类型定义了运算符<<,则列出成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21146992/

相关文章:

c++ - 从 Point2f 中提取数据

c++ - 自动循环和优化

c++ - 模拟 const 值以进行测试

c++ - std::function 和错误:没有匹配的函数来调用

c++ - 用 C++ 编写一个简单的面向对象图

c++ - 错误 : control Reaches end of non void function

c++ - SetWindowPos 对工具提示没有影响

c++ - POCO 记录器包装器

c++ - 如何使用 std::lock_guard 锁定对 std::map 的读写访问?

c++ - 以 weak_ptr 作为参数的函数重载决议