2

大多数情况下,简单成员函数的 C++17 推断返回类型可以轻松转换为 C++11 尾随返回类型。

例如,成员函数在

template<typename T>
struct X
{
    T a;
    auto f() { return frob(a); }
};

变成

auto f() -> decltype(frob(a)) { return frob(a); }

考虑到using namespace在类主体内的顶级范围内不允许这样做,您如何为以下内容编写尾随返回类型?

namespace widget
{
    template<typename S>
    int froz(S&&);
}

template<typename T>
struct Y
{
    T b;
    auto g() { using namespace widget; return froz(b); }
};

(例如,在调用std::swap, std::begin,时使用带有回退的参数相关查找非常常见std::end

template<typename T>
struct Z
{
    T container;
    auto h() { using namespace std; return begin(container); }
};
4

2 回答 2

3

怎么样:

template<typename T>
struct Z
{
    T container;
    auto h() -> decltype(
        [] 
        {
            Z<T>* z;
            using namespace std; return begin(z->container);
        }()

    ) { using namespace std; return begin(container); }
};
于 2020-11-12T18:19:49.417 回答
2

这是我发现的最好的解决方法,引入了一个帮助命名空间来using namespace尽可能接近地托管:

namespace impl
{
    using namespace std;

    template<typename T>
    struct Z
    {
        T container;
        auto h() -> decltype(begin(container)) { return begin(container); }
    };
}
using impl::Z;

为了不影响整个类,它可以用来使 Ayxandecltype在辅助函数上使用的想法在 C++11 中起作用:

namespace impl
{
    using namespace std;

    template<typename T>
    auto begin(T&& t) -> decltype(begin(std::forward<T&&>(t)));
}

template<typename T>
struct Z
{
    T container;
    auto h() -> decltype(impl::begin(container)) { using namespace std; return begin(container); }
};
于 2020-11-12T18:27:56.923 回答