如何在构造函数初始化列表中启用ADL?例如,我们假设我有bignum
具有命名空间级abs
功能。现在我想编写一个类Foo
,用传递给构造函数的实例的绝对值初始化它的成员;它应该使用名称空间级abs
(如果存在)和std::abs
否则:
template<typename T>
struct Foo
{
T _data;
Foo(T data):
_data(abs(data)) // I want find abs with ADL here
{}
};
无论如何在课堂范围内禁止使用声明,我也不想污染&#34;污染&#34;命名空间。如何启用ADL以使其在构造函数初始化列表中工作?
答案 0 :(得分:7)
您可以使用lambda表达式直接从初始化列表中解决此问题:它允许您内联编写所需的帮助函数,并且该辅助函数可以包含using std::abs;
。
template<typename T>
struct Foo
{
T _data;
Foo(T data):
_data([&](){ using std::abs; return abs(data); }())
{}
};
答案 1 :(得分:4)
您可以创建一个免费或static
本地帮助程序函数,并允许ADL在那里进行ocurr:
template <typename T>
struct Foo
{
T _data;
Foo(T data):
_data(abs(data))
{}
template <typename X>
using delete_reference = typename std::remove_reference<X>::type;
template <typename U>
static delete_reference<U> abs(U&& x)
{
using std::abs;
return abs(std::forward<U>(x));
}
};
答案 2 :(得分:1)
使用帮助函数:
namespace detail
{
template <typename Arg>
auto invoke_abs(Arg&& arg)
{
using std::abs;
return abs(std::forward<Arg>(arg));
}
}
Foo(T data)
: _data{detail::invoke_abs(std::forward<T>(data))}
{ }