[英]C++ ADL: Call a function from the namespace which a particular type belongs to
[英]C++ ADL of a function in another namespace
我有一个函数模板printSize
调用重载函数getSize
之前getSize
声明。 为了使程序结构更清晰,我希望将两个函数放在不同的命名空间A
和B
,如注释的代码行所示。 但是,ADL随后将找不到getSize
。
实际上, printSize
和getSize
是在不同的头文件中实现的。 因此,我不能放置using namespace
指令。
#include <array>
#include <iostream>
#include <string>
namespace A {
template <typename T> struct tag {};
template <typename T>
void printSize(const T &data)
{
size_t data_size = getSize(data, tag<T>{});
//size_t data_size = B::getSize(data, tag<T>{});
std::cout << "Size: " << data_size << std::endl;
}
//} // namespace A
//namespace B {
constexpr size_t getSize(const int &, tag<int>)
{
return sizeof(int);
}
size_t getSize(const std::string &str, tag<std::string>)
{
return str.size();
}
template <typename T, size_t N>
size_t getSize(const std::array<T, N> &array, tag<std::array<T, N>>)
{
size_t array_size = 0;
for (const T &element : array)
array_size += getSize(element, tag<T>{});
return array_size;
}
} // namespace A/B
int main()
{
int a;
A::printSize(a);
std::array<std::string, 2> arr = {{"foo", "foobar"}};
A::printSize(arr);
return 0;
}
有没有一种方法可以使此代码与在不同名称空间中定义的printSize
和getSize
一起编译?
一种解决方案是将标记放入B
名称空间,然后将其拉入A
namespace B {
template <typename T> struct tag {};
}
namespace A {
using B::tag;
}
现在,因为tag
来自B
名称空间,所以它将B
与ADL关联。
您可以使用using
声明从另一个名称空间引入名称。 例如:
template <typename T>
void printSize(const T &data)
{
using B::getSize;
std::size_t data_size = getSize(data, tag<T>{});
std::cout << "Size: " << data_size << std::endl;
}
getSize
取决于模板参数T
,因此在查找的第二阶段(实例化此模板时)将使用ADL查找用户提供的其他getSize
。 这里B::getSize
应该在printSize
和tag
本身似乎是多余的之前声明。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.