gpt4 book ai didi

c++ - 通用 2D 点作为 C++ 中的输入

转载 作者:行者123 更新时间:2023-12-01 14:54:00 24 4
gpt4 key购买 nike

我正在为模板库编写通用代码。我的输入应该是或包含某种形式的二维坐标。为了通用,我的代码期望以某种方式在用户代码中实现以下两个函数:

template <typename T, typename CoordinateType>
CoordinateType get_x(const T&);

template <typename T, typename CoordinateType>
CoordinateType get_y(const T&);

尽管如此,我在想:对于一些非常琐碎的情况,我是否可以减轻图书馆用户实现这两个功能的负担?也许通过将 SFINAE 与这两个函数的一些默认实现一起使用?

例如,如果 T.x.y公共(public)成员只使用那些,或者如果给定 T.x().y()访问者只需调用它们,或者 .get_x().get_y()以及 .getX().getY()等等...

最佳答案

这是使用 std::is_detected 的解决方案和 if constexpr (所以 C++17 兼容):

template<class T>
using member_x = decltype(std::declval<T&>().x);
template<class T>
using member_y = decltype(std::declval<T&>().y);

template<class T>
using accessor_x = decltype(std::declval<T&>().x());
template<class T>
using accessor_y = decltype(std::declval<T&>().y());

template<class T>
using brackets = decltype(std::declval<T&>()[0]);


template<class T>
auto get_x_impl(const T& vec)
{
if constexpr (std::experimental::is_detected_v<member_x, T>)
return vec.x;
else if constexpr (std::experimental::is_detected_v<accessor_x, T>)
return vec.x();
else if constexpr (std::experimental::is_detected_v<brackets, T>)
return vec[0];
else
return get_x(vec);
}

https://godbolt.org/z/_Soaeb

但是,特化 get_x 还是有问题的。 - 无法推断返回类型,但必须在调用中指定(但库不知道 getter 应该返回什么类型!)。按照标准的发展方向,不鼓励提供函数模板作为定制点,类模板更加健壮。这在这里会有所帮助:
  • 该库提供了一个类模板供用户专门化(可能在单独的命名空间中):
    template<class T>
    struct getter;
  • 图书馆使用它:
    return getter<T>::get_x(val);
  • 用户专门研究它:
    template<>
    struct getter<TypeToSpecializeFor>
    {
    static auto get_x(const TypeToSpecializeFor&) { /*...*/ }
    static auto get_y(const TypeToSpecializeFor&) { /*...*/ }
    };

  • https://godbolt.org/z/W4LPt8

    所有涉及的标识符的命名当然取决于口味。

    进一步阅读: https://quuxplusone.github.io/blog/2018/03/19/customization-points-for-functions/

    关于c++ - 通用 2D 点作为 C++ 中的输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59320539/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com