0

我希望能够将任何内容附加std::vector<T>到输出流。我找到了这段代码:

#ifndef DEBUG_H_
#define DEBUG_H_

#include <vector>

template < class T >
std::ostream& operator << (std::ostream& os, const std::vector<T>& v)
{
    os << "[";
    for (typename std::vector<T>::const_iterator ii = v.begin(); ii != v.end(); ++ii)
    {
        os << " " << *ii;
    }
    os << "]";
    return os;
}


#endif /* DEBUG_H_ */

并放入标题中Debug.h。如何在整个项目中使用此运算符?

编辑:我已经验证这在单元测试中有效:

#include "Debug.h"

TEST_F(AuxGTest, testVectorDebug) {
    std::vector<int> vec(10, 42);
    std::cout << "vec: " << vec << std::endl;
}

但是将它与 log4cxx 的日志语句一起使用是行不通的:

#include <log4cxx>
#include "Debug.h"

namespace Foo {
    class Bar { 
        void foo() {
            std::vector<int> vec(10, 42);
            DEBUG("vec: " << vec);
        }

    }

}

这将导致以下编译器消息:

/usr/local/Cellar/log4cxx/0.10.0/include/log4cxx/helpers/messagebuffer.h:190:47: error: cannot bind 'std::basic_ostream<char>' lvalue to 'std::basic_ostream<char>&&'
4

2 回答 2

3

你想在哪里使用它?正如声明的那样,它位于全局命名空间中,因此 ADL 不会找到它,除非T它是在全局命名空间中定义的类型。如果您在全局命名空间以外的命名空间中,并且operator<<该命名空间中有一个(这会隐藏它),则不会通过正常查找找到它。如果在模板中调用它也不会找到它,如果任何参数是依赖的,因为依赖名称查找只使用 ADL。

当然,除了玩具程序,你真的不想这样做。的不同用途std::vector需要不同的输出格式;最好将 包装 std::vector在一个类中,并operator<<为该类定义每个不同的语义用途。(对于玩具程序,您可以在命名空间中定义运算符std。未定义的行为,但由于没有其他人会看到代码,或者必须维护它,如果它不起作用,它也不是世界末日...... )

编辑:

因为您似乎将它用于某种跟踪或调试:这是支持统一输出的一种情况std::vector,因为它用于输出内部状态。另一方面,在这种情况下,通常ostream会被包裹起来,例如:

class Logger
{
    std::ostream* myDest;
public:
    Logger( std::ostream* dest )
        : myDest( dest )
    {
    }

    template <typename T>
    Logger& operator<<( T const& value )
    {
        if ( myDest != NULL ) {
            *myDest << value;
        }
        return *this;
    }
};

这允许运行时配置日志记录(加上自动插入和之类的东西__FILE____LINE__如果您使用宏来获取 的实例Logger);您的宏DEBUG 可能类似于:

#define DEBUG getLogger( TRACELEVEL_DEBUG, __FILE__, __LINE__ )

wheregetLogger是一个全局函数,它返回一个使用正确(或空指针,如果该级别的日志记录不是活动的)Logger 初始化的值。ostream完成此操作后,您可以添加特殊功能,例如:

template <typename T>
Logger& Logger::operator<<( std::vector<T> const& value )
{
    if ( myDest != NULL ) {
        //  your code here...
    }
    return *this;
}

由于<<运算符的参数之一将是 的实例Logger,因此 ADL 将找到运算符,无论如何。

于 2013-04-23T16:07:35.893 回答
0

关于 log4cxx 的用户定义运算符有一个类似的问题。我通过建议将运算符放在命名空间中来回答log4cxx::helpers这个问题。看 。

于 2014-01-10T05:39:48.550 回答