3

如何在构造函数初始化列表中启用 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
    {}
};

无论如何,在类范围内都禁止使用声明,我不想“污染”命名空间。如何启用 ADL 以便它在构造函数初始化列表中工作?

4

3 回答 3

8

您可以使用 lambda 表达式直接从初始化器列表中解决此问题:它允许您内联编写所需的辅助函数,并且该辅助函数可以包含using std::abs;.

template<typename T>
struct Foo
{
    T _data;

    Foo(T data):
        _data([&](){ using std::abs; return abs(data); }())
    {}
};
于 2014-05-25T21:29:46.020 回答
4

您可以创建一个免费的或static本地的辅助函数并允许 ADL 在那里发生:

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));
    }
};
于 2014-05-25T21:17:55.627 回答
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))}
{ }
于 2014-05-25T21:19:50.947 回答