ADL在构造函数初始化列表中

时间:2014-05-25 21:11:45

标签: c++ c++11 argument-dependent-lookup initialization-list

如何在构造函数初始化列表中启用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以使其在构造函​​数初始化列表中工作?

3 个答案:

答案 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))}
{ }