首页 > 解决方案 > 另一个命名空间中函数的 C++ ADL

问题描述

我有一个在声明之前printSize调用重载函数的函数模板。为了使我的程序结构更清晰,我想将这两个函数放在不同的名称空间中,并且正如注释的代码行所示。但是,ADL 将无法找到.getSizegetSizeABgetSize

实际上,printSizegetSize是在不同的头文件中实现的。因此,我不能提出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;
}

有没有办法让这段代码在不同的命名空间中编译printSizegetSize定义?

标签: c++argument-dependent-lookup

解决方案


一种解决方案是将标签放入B命名空间,然后将其拉入A.

namespace B {
    template <typename T> struct tag {};
}

namespace A {
   using B::tag;
}

现在,因为tag来自B命名空间,所以它将B为 ADL 关联。


推荐阅读