参数相关查找和流运算符重载
Argument Dependent Lookup and stream operators overloading
>我有一个库,它公开了某种容器struct
,我想在其中收集来自不同通用类型的数据,这些数据可能来自库的同一namespace
以及来自std
命名空间的数据,例如array
或tuple
或pairs
。
此容器具有一个print_all
方法,该方法将为容器中的所有元素调用operator<<
。这样的运算符应该由库的用户提供。
测试库,我正在使用不同的模板参数进行T
,但我不太关心print_all
方法打印的内容。出于测试目的,我只关心无论测试哪个T
都打印示例字符。实际上,我正在使用Google测试框架的真实代码,并且所测试方法的行为确实断言对于提供的每种数据类型都是相同的。
我试图提供operator<<
的通用版本和它的两个特定版本。您可以在#if
指令之间看到它们。两个编译分支都没有正确编译,很可能是因为违反了 König 查找规则。但无论如何,我想做的事情应该很容易以某种方式实现。我错过了什么?
下面是示例代码:
#include <algorithm>
#include <iostream>
#include <vector>
namespace my
{
template<typename DataType>
struct Container
{
void print_all( std::ostream& os ) const
{
std::for_each(std::begin(data),
std::end(data),
[&os](const DataType& value)
{
os << value;
});
}
std::vector<DataType> data;
};
namespace test
{
struct Data
{
std::byte data[4];
};
using Array = std::array<std::byte,4>;
#if 0
template<typename T>
std::ostream& operator<<(std::ostream& os, const T& data)
{
return os << 'X';
}
#else
std::ostream& operator<<(std::ostream& os, const Data& data)
{
return os << 'X';
}
std::ostream& operator<<(std::ostream& os, const Array& data)
{
return os << 'X';
}
#endif
void run()
{
// Test with custom data
{
Container< Data> container;
container.data.resize(1);
container.print_all( std::cout );
}
// Test with std data
{
Container< Array> container;
container.data.resize(1);
container.print_all( std::cout );
}
}
} // namespace test
} // namespace my
int main()
{
my::test::run();
return 0;
}
ADL 会查看与参数关联的命名空间。
using Array = std::array<std::byte,4>;
此类型test::Array
是别名。 出于 ADL 目的而与之关联的命名空间是std
。test
与它无关。 ADL 只会在std
中查找。 不允许在std
中添加运算符;如果违反该规定,则程序格式不正确,无需诊断。 ADL 无法帮助你,因为它只帮助拥有与参数关联的命名空间的人。
您希望在std
中支持的任何<<
都需要在namespace my
中,在print_all
函数之前定义。
你的Data
代码在我看来是有效的,我认为你的问题写得很差,因为它暗示os <<Data
不起作用。 如果我是wromg amd,它不起作用,这是因为一些错别字;ADL 在struct
上工作正常,但在别名上则不行。 将来,请在代码不起作用时包含完整的错误消息。
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- <T> 通过模板化运算符重载将 std::complex 乘以双倍
- C++20概念:需要运算符重载
- 使用赋值运算符重载从类中返回jobject
- 在运算符重载定义中使用成员函数(const错误)
- 字节到位运算符重载C++
- 为什么在运算符重载时需要参考?
- 类中 c++ 的运算符 + 重载
- 算术复合运算符重载为非成员
- 运算符重载 (+),用于添加两个具有 C++ 的数组
- 交换运算符 + 重载会导致无限递归
- 如何理解新的运算符重载?
- 向量保持复数的运算符重载
- 如何创建运算符重载?
- 链接列表运算符重载没有打印出我想要的内容
- C++:需要帮助了解运算符重载错误
- 使用模板化运算符重载 XOR 运算符失败
- 如何确保接受的C++模板类型使运算符重载?
- 运算符重载使用运算符+添加类模板