gpt4 book ai didi

c++ - Boost Test BOOST_CHECK_EQUAL 类型可转换为数组

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:23:03 26 4
gpt4 key购买 nike

这是一个使用 Boost Test 的简单程序,它的行为“很奇怪”:

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE foo
#include <boost/test/unit_test.hpp>

class C
{
public:
C(char* str) : m_str(str) {}
operator char*() const { return m_str; }
char* get() const { return m_str; }

private:
char* m_str;
};


BOOST_AUTO_TEST_CASE(test1)
{
char s1[] = "hello";
char s2[] = "hello";
C c1(s1);
C c2(s2);
BOOST_CHECK_EQUAL(s1, s2); // check 1: passes
BOOST_CHECK_EQUAL(c1, c2); // check 2: fails (why?)
BOOST_CHECK_EQUAL(c1.get(), c2.get()); // check 3: passes
}

如果你运行它,它会在比较 c1 和 c2 时报告失败,而它似乎应该通过。原因是 Boost Test 中的这段代码(我使用的是 1.51):

// this is called for check 2
template <class Left, class Right>
predicate_result equal_impl( Left const& left, Right const& right )
{
return left == right;
}

// this is called for checks 1 and 3
predicate_result BOOST_TEST_DECL equal_impl( char const* left, char const* right );
inline predicate_result equal_impl( char* left, char* right ) { return equal_impl( static_cast<char const*>(left), static_cast<char const*>(right) ); }

// this decides which comparator to call
struct equal_impl_frwd {
// this is called for checks 2 and 3
template <typename Left, typename Right>
inline predicate_result
call_impl( Left const& left, Right const& right, mpl::false_ ) const
{
return equal_impl( left, right );
}

// this is called for check 1
template <typename Left, typename Right>
inline predicate_result
call_impl( Left const& left, Right const& right, mpl::true_ ) const
{
return (*this)( right, &left[0] );
}

template <typename Left, typename Right>
inline predicate_result
operator()( Left const& left, Right const& right ) const
{
typedef typename is_array<Left>::type left_is_array;
return call_impl( left, right, left_is_array() );
}
};

所以首先,BOOST_CHECK_EQUAL 在编译时决定参数是否为数组。在检查 1 中,它们是,并且数组降级为指针。然后它决定如何比较参数。如果参数是 char* 类型,它会将它们作为 C 字符串进行比较。否则,它使用运算符 ==。所以问题是 C 类不是 char*,所以检查 2 是使用运算符 == 完成的。但是类 C 没有运算符 ==,因此编译器决定将 c1 和 c2 隐式转换为 char*,此时运算符 == 已定义,但将它们作为地址而不是 C 字符串进行比较。

所以我们最终遇到了一个相当奇怪的情况:Boost Test 打算始终将 char* 参数作为 C 字符串进行比较,但它不知道比较 c1 和 c2 的唯一方法是将它们转换为 char*。

我的问题是,我们如何才能在这里做得更好?例如,有没有一种方法可以在编译时理解,当为 c1 和 c2 调用运算符 == 时,它将使用它们到 char* 的隐式转换?这有点像在编译时使用 decltype() 来确定表达式的返回类型,只是我们需要确定表达式的参数类型(即 c1 == c2)。

最佳答案

我认为您无法真正支持这种情况,因为我能想到的所有 SFINAE 技术都会遇到模棱两可的重载。

事实上,这正是 Boost 的记录限制 has_equal_to<A,B,R> 类型特征:

There is an issue if the operator exists only for type A and B is convertible to A. In this case, the compiler will report an ambiguous overload.

关于c++ - Boost Test BOOST_CHECK_EQUAL 类型可转换为数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23146182/

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