透明操作员函数

时间:2013-07-19 02:19:51

标签: c++ c++11 c++14 visual-studio-2013

Visual Studio 2013 Preview支持名为(根据this页面)“透明运算符函数”的C ++ 14功能。我不清楚这意味着什么。我找到的最接近的C ++ 14提案就是这个,但我不确定它是否是同一个东西: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3421

我正在寻找一个更明确的解释,它是什么,为什么它是一个改进,也许是一个证明其使用的片段。

1 个答案:

答案 0 :(得分:22)

透明运算符仿函数提议可以使用位于<functional>的通用仿函数。我个人认为该提案本身有一个非常好的例子,可以帮助说明它的必要性。但是我会继续尝试解释它。

假设你有一个功能,一个非常基本的功能提醒你:

template<typename T, typename U>
auto less_than(T&& t, U&& u) -> decltype(std::forward<T>(t) < std::forward<U>(u)) {
    return std::forward<T>(t) < std::forward<U>(u);
}

但是,您希望在<algorithm>标头中使用此通用功能。你有两个选择,使它成为一个struct functor:

struct MyLessThanFunctor {
    template<typename T, typename U>
    auto operator()(T&& t, U&& u) -> decltype(std::forward<T>(t) < std::forward<U>(u)){
        return std::forward<T>(t) < std::forward<U>(u);
    }
};

或者在C ++ 14中,制作一个多态lambda:

[](auto&& t, auto&& u) -> decltype(auto) { 
    return std::forward<decltype(t)>(t) < std::forward<decltype(u)>(u); 
}

在像这样的算法中使用时,两者都非常冗长:

int main() {
    std::vector<int> v = {112,12,1281271,1919101,29181,412,1 };
    std::sort(std::begin(v), std::end(v), MyLessThanFunctor()); // one
    std::sort(std::begin(v), std::end(v), [](auto&& t, auto&& u) -> decltype(auto) { 
        return std::forward<decltype(t)>(t) < std::forward<decltype(u)>(u); 
    });
}

这项提案的目的是通过这样做来使其更加紧凑和通用:

std::sort(std::begin(v), std::end(v), std::less<>());

这为您提供了完美的转发并解决了因更改容器而导致的截断或问题,而不是文件中提到的容器指定的基础类型。

假设您有一个非广义仿函数:

struct Functor {
    bool operator()(uint32_t a, uint32_t b) {
        return a < b;
    }
};

你将它与std::vector<uint32_t>一起使用它可以正常工作,但是你忘记了你的仿函数没有被推广并且与你的std::vector<uint64_t>一起使用。你能看到出现的问题吗?在比较之前,元素将被截断,这可能不是用户想要的。广义仿函数会在出现之前为您解决此问题。