模板超载优先级

时间:2016-06-20 23:20:04

标签: c++ templates

我希望模板函数有两个重载但有一个优先。我正在尝试定义一个size()函数,该函数使用size成员函数(如果可用)但回退到使用std::begin()std::end()(这需要说std::forward_list())。这就是他们的样子:

template <class Container>
constexpr auto size(const Container& cont) -> decltype (cont.size())
{
    return cont.size();
}

template <class Container>
auto size(const Container& cont) -> decltype (
    std::distance(std::begin(cont), std::end(cont)))
{
    return std::distance(std::begin(cont), std::end(cont));
}

问题是编译器无法确定哪个重载用于具有size()和begin()/ end()的容器。如何在可能的情况下选择第一个实现? (我知道SFINAE是解决方案的一部分,但我对奥术艺术的了解不足以明白这一点)

另外(无关),是否有更简单的方法来声明第二个函数的返回类型?

3 个答案:

答案 0 :(得分:1)

又一个,以标准的重载决议作为决胜局:

namespace details {
    template <class Container>
    constexpr auto size(const Container& cont, int) -> decltype (cont.size())
    {
        return cont.size();
    }

    template <class Container>
    auto size(const Container& cont, ...) -> decltype (
        std::distance(std::begin(cont), std::end(cont)))
    {
        return std::distance(std::begin(cont), std::end(cont));
    }
}

template <class Container>
auto size(const Container& cont) -> decltype(details::size(cont, 0)) {
    return details::size(cont, 0);
}

答案 1 :(得分:0)

您将创建一个特征,指定是否存在A16 Name B16 Value A17 A B17 1 A18 B B18 2 A19 C B19 3 函数。然后使用size()使用该特征,并选择性地启用您希望选择的功能,禁用相应的其他功能。

这应该可以解决问题:

std::enable_if

答案 2 :(得分:0)

另一个使用标签发送的答案:

if ( "began" == event.phase ) then
    -- This is the "keyboard has appeared" event
    -- In some cases you may want to adjust the interface when the keyboard appears.
    if (event.target.id == "password") then
        event.target.isSecure = true