C ++推导出指向成员模板参数的指针

时间:2018-03-14 13:41:14

标签: c++ templates c++17 type-deduction

我正在尝试使用C ++ 17功能为字典比较编写模板化版本:

public abstract class Mammal { }

public class Cat: Mammal { }

public class Dog : Mammal { }

但是,我的示例不能使用最新版本的GCC进行编译:

#include <type_traits>
#include <set>
#include <vector>
#include <iostream>

namespace compare
{
    template <typename T, auto P, auto ...Ps>
    bool less(const T &t1, const T &t2)
    {
        if constexpr (sizeof...(Ps) == 0)
        {
            return t1.*P < t2.*P;
        }
        else
        {
            if (t1.*P == t2.*P)
            {
                return less<Ps...>(t1, t2);
            }
            else
            {
                return t1.*P < t2.*P;
            }
        }
    }
}

struct my_type
{
    int i = 0;
    std::set<int> s;
};

int main()
{
    my_type t1, t2;

    t2.i = -1;

    std::cout << std::boolalpha << compare::less<my_type, &my_type::i, &my_type::s>(t1, t2) << std::endl;

    return 0;

}

有趣的是,编译器输出没有说明无法推断出哪个模板参数。我知道如何以前C ++ 17的方式实现它。我做错了什么?

1 个答案:

答案 0 :(得分:2)

您遗失了T中的less<Ps...>

namespace compare
{
    template <typename T, auto P, auto ...Ps>
    bool less(const T &t1, const T &t2)
    {
        if constexpr (sizeof...(Ps) == 0)
        {
            return t1.*P < t2.*P;
        }
        else
        {
            if (t1.*P == t2.*P)
            {
                return less<T, Ps...>(t1, t2);
            }
            else
            {
                return t1.*P < t2.*P;
            }
        }
    }
}

See it live

除此之外:为了符合标准库定义概念比较的方式,我建议删除使用==,而不是

if (return t1.*P < t2.*P)
{
    return true;
}
if (return t2.*P < t1.*P)
{
    return false;
}
return less<T, Ps...>(t1, t2);