gpt4 book ai didi

c++ - 如何在模板推导中使用 ADL?

转载 作者:行者123 更新时间:2023-11-30 02:16:40 27 4
gpt4 key购买 nike

我有一个带有类内定义友元函数的类,我最好不要修改它(它来自已经部署的 header )

#include <numeric>
#include <vector>

namespace our_namespace {
template <typename T>
struct our_container {

friend our_container set_union(our_container const &, our_container const &) {
return our_container{};
}
};
} // namespace our_namespace

set_union未在结构或命名空间之外声明,但通常可以通过参数相关查找找到(参见 Access friend function defined in class )。但是,我遇到了一种情况,我需要对函数进行未评估(即没有要评估的参数)以进行模板类型推导。更具体地说,我想将 friend 函数用作 std::accumulate 中的二元运算。 :

auto foo(std::vector<our_namespace::our_container<float>> in) {      
// what I really wanted to do:
return std::accumulate(std::next(in.begin()), in.end(), *in.begin(),
set_union);
}

到目前为止我发现的唯一解决方法是将函数调用包装到 lambda 中:

auto foo(std::vector<our_namespace::our_container<float>> in) {    
// what I ended up doing:
return std::accumulate(std::next(in.begin()), in.end(), in[0],
[](our_namespace::our_container<float> const& a, our_namespace::our_container<float> const& b) {return set_union(a,b);});
}

(当然我可以定义一个与 lambda 功能相同的函数)。

我试过:

  • set_union 指定命名空间(我通常会绕过 ADL,但 set_union 不在命名空间中)
  • 拼出模板参数 set_union<our_container> (但是 set_union 查找在 set_union 的模板参数推导中没有失败,并且本身没有模板化)
  • 说出 set_union 的类型与 …,decltype(set_union) set_union); …除了,这里查找set_union出于同样的原因失败,并为 set_union 提供参数在decltype只会触发其评估并导致返回类型 set_union而不是它的类型。

还有其他方法可以使用accumulate吗?使用 ADL 而不是这个 lambda?

最佳答案

在我看来,使用 lambda 是最好的方法。

正如@NathanOliver 所建议的,您可以将其缩短为:

[](auto const& a, auto const& b) {return set_union(a,b);}

如果你坚持,还有一个替代方案,但它有点难看。

specifying the namespace for set_union (what I usually do to get around ADL, but set_union isn't in a namespace)

命名空间中,但只能通过 ADL 找到。

如果您在类之外重新声明它,您将能够通过常规查找找到它:

namespace our_namespace
{
our_container<float> set_union(our_container<float> const &, our_container<float> const &);
}

auto foo(std::vector<our_namespace::our_container<float>> in)
{
// what I really wanted to do:
return std::accumulate(std::next(in.begin()), in.end(), *in.begin(),
our_namespace::set_union<float>);
}

不幸的是,您不能将其声明为模板(因为它不是模板)。

关于c++ - 如何在模板推导中使用 ADL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54580395/

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