使函数仅获取每对存在的第一个值

Making a function take only the first value from every pair present

本文关键字:存在 第一个 函数 获取      更新时间:2023-10-16

我需要使一个函数仅获取每个传递给其参数的每个 std::pair的第一个值。不使用std::pair类型的值将不变。我的以下解决方案仅适用于需要两个参数的函数。我需要知道如何将其推广到任何数量的参数。

#include <type_traits>
template <typename T, typename = void>
struct has_first_type : std::false_type { };
template <typename T>
struct has_first_type<T, std::void_t<typename T::first_type>> : std::true_type { };
template <typename R, typename T, typename U, typename = void> struct act_on_first;
template <typename R, typename T, typename U>
struct act_on_first<R, T, U, std::enable_if_t<has_first_type<T>::value && has_first_type<U>::value>> {
    template <typename F>
    static R execute (const T& t, const U& u, F f) {
        return f(t.first, u.first);
    }
};
template <typename R, typename T, typename U>
struct act_on_first<R, T, U, std::enable_if_t<has_first_type<T>::value && !has_first_type<U>::value>> {
    template <typename F>
    static R execute (const T& t, const U& u, F f) {
        return f(t.first, u);
    }
};
template <typename R, typename T, typename U>
struct act_on_first<R, T, U, std::enable_if_t<!has_first_type<T>::value && has_first_type<U>::value>> {
    template <typename F>
    static R execute (const T& t, const U& u, F f) {
        return f(t, u.first);
    }
};
template <typename R, typename T, typename U>
struct act_on_first<R, T, U, std::enable_if_t<!has_first_type<T>::value && !has_first_type<U>::value>> {
    template <typename F>
    static R execute (const T& t, const U& u, F f) {
        return f(t, u);
    }
};
struct foo {
    template <typename... Args>
    std::size_t operator()(Args&&...) { return sizeof...(Args); }  // Simple example only.
};
template <typename T, typename U>
std::size_t bar (const T& t, const U& u) {
    return act_on_first<std::size_t, T, U>::execute(t, u, foo());
}
// Testing
#include <iostream>
int main() {
    std::pair<int, bool> k = {3, true};
    std::pair<int, char> m = {5, 't'};
    std::cout << bar(k,m) << 'n';  // 2
    std::cout << bar(k,5) << 'n';  // 2
    std::cout << bar(3,m) << 'n';  // 2
    std::cout << bar(3,5) << 'n';  // 2
}

写一个变压器,要么给您 .first for pairs,要么只是返回其参数:

template <typename T> T const& take_first(T const& x) { return x; }
template <typename T, typename U>
T const& take_first(std::pair<T, U> const& p) { return p.first; }
template <typename... Args>
std::size_t bar(Args const&... args) {
    return foo{}(take_first(args)...);
}