gpt4 book ai didi

c++ - 我怎样才能允许将 vector 传递给 INFO()、CAPTURE()、WARN() 等,同时避免非法扩展 std namespace ?

转载 作者:太空宇宙 更新时间:2023-11-04 13:05:28 25 4
gpt4 key购买 nike

在 Catch Unit Test v1.8.1 中,使用 gcc 6.2.0,我试图在测试失败时通过将 vector 传递给 INFO(...) 来方便地输出 vector 的内容。或 CAPTURE(...) .为此,我重载了流插入运算符:

#include <Catch/single_include/catch.hpp>
#include <vector>
#include <iostream>

#define THIS_WORKS_BUT_EXTENDING_NAMESPACE_STD_IS_ILLEGAL
#ifdef THIS_WORKS_BUT_EXTENDING_NAMESPACE_STD_IS_ILLEGAL
namespace std {
#endif

std::ostream& operator<<( std::ostream& os, const std::vector<int>& v ) {
for ( const auto& e : v ) {
os << e << " ";
}
return os;
}

#ifdef THIS_WORKS_BUT_EXTENDING_NAMESPACE_STD_IS_ILLEGAL
} //namespace std
#endif

int some_operation_on_vector( const std::vector<int>& v ) {
return 1;
}

SCENARIO( "some scenario" )
{
GIVEN( "a vector" )
{
const auto the_vector = std::vector<int>{ 1, 2, 3, 4, 5 };

WHEN( "some result is calculated from the vector" )
{
const auto actual_result = some_operation_on_vector( the_vector );

THEN( "the result should be correct. If not, print out the vector." )
{
const auto expected_result = 0;

CAPTURE( the_vector ); // <--------
//^^^^
//How do I legally make this work?

REQUIRE( expected_result == actual_result );
}
}
}
}

如果我(非法)扩展 std namespace 如上,然后它可以工作,我看到了所需的输出:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
catchtestexample is a Catch v1.8.1 host application.
Run with -? for options

-------------------------------------------------------------------------------
Scenario: some scenario
Given: a vector
When: some result is calculated from the vector
Then: the result should be correct. If not, print out the vector.
-------------------------------------------------------------------------------
ExampleTest.cpp:91
...............................................................................

ExampleTest.cpp:95: FAILED:
REQUIRE( expected_result == actual_result )
with expansion:
0 == 1
with message:
the_vector := 1 2 3 4 5

===============================================================================
test cases: 1 | 1 failed
assertions: 1 | 1 failed

但是为了合法,当我尝试移动 operator<<重载 std命名空间并进入全局命名空间(通过注释掉 #define THIS_WORKS_BUT_EXTENDING_NAMESPACE_STD_IS_ILLEGAL ),由于将 vector 传递给 CAPTURE(),代码无法编译宏。

根据 Catch docs ,我尝试更换 operator <<Catch::toString 重载过载:

#include <string>
#include <sstream>

namespace Catch {
std::string toString( const std::vector<int>& v ) {
std::ostringstream ss;
for ( const auto& e : v ) {
ss << e << " ";
}
return ss.str();
}
}

或使用 Catch::StringMaker专业:

#include <string>
#include <sstream>

namespace Catch {
template<> struct StringMaker<std::vector<int>> {
static std::string convert( const std::vector<int>& v ) {
std::ostringstream ss;
for ( const auto& e : v ) {
ss << e << " ";
}
return ss.str();
}
};
}

但在任何一种情况下,由于将 vector 传递给 CAPTURE(),测试仍然无法编译。宏。

Catch 文档说要放置 operator<<重载到与您的类型相同的命名空间,但是 std::vector不是我的类型,并将该重载放入命名空间 std是非法的。

但我找到的唯一方法是 CAPTURE() (或 INFO()WARN() 等)接受 std::vector参数是非法放置 operator<<重载到命名空间 std .

是否有适当、合法的方式来做到这一点?

最佳答案

我想我找到了一个有效的答案。 (编辑:请参阅 other answer 以获得更好的解决方案。)

而不是把 operator<<重载到 std命名空间,将其放入 Catch命名空间编译并给出所需的行为:

namespace Catch {

std::ostream& operator<<( std::ostream& os, const std::vector<int>& v ) {
for ( const auto& e : v ) {
os << e << " ";
}
return os;
}

}

Catch docs说把operator<<重载到与您的类型相同的 namespace 中:

operator<< overload for std::ostream

This is the standard way of providing string conversions in C++ - and the chances are you may already provide this for your own purposes. If you're not familiar with this idiom it involves writing a free function of the form:

   std::ostream& operator<<( std::ostream& os, T const& value ) {
os << convertMyTypeToString( value );
return os;
}

(where T is your type and convertMyTypeToString is where you'll write whatever code is necessary to make your type printable - it doesn't have to be in another function).

You should put this function in the same namespace as your type. [Emphasis mine]

Alternatively you may prefer to write it as a member function:

   std::ostream& T::operator<<( std::ostream& os ) const {
os << convertMyTypeToString( *this );
return os;
}

但是因为 std::vector 不是我的类型,它位于命名空间 std 中,我无法按照文档所说的去做。

所以可以把operator<<重载到 Catch命名空间代替?它有效,但是可以吗?如果我这样做会发生坏事吗?文档确实说可以重载 toString进入 Catch 命名空间,所以这对 operator<< 没问题吗?也有过载?

关于c++ - 我怎样才能允许将 vector 传递给 INFO()、CAPTURE()、WARN() 等,同时避免非法扩展 std namespace ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42621378/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com