c++ varargs/variadic 函数具有两种类型的参数一起重复(交替)

c++ varargs/variadic function with two types of arguments that repeat together (alternating)

我可以找到有关如何使用一种重复的类型编写可变参数函数的示例,如 StringFormat() 但我需要编写一个其中两种不同类型交替重复的示例。

用法需要如下所示:

MyFunc(stringVar, intVar1, doubleVar1);
MyFunc(stringVar, intVar1, doubleVar1, intVar2, doubleVar2, intVar3, doubleVar3, intVar4, doubleVar4);

函数总是有一个字符串输入和至少一个 int 和一个 double,但 int 和 double 会一起重复。

如果可能的话,我还需要一种方法让文档告诉您您使用的是哪种 arg 类型。也许文档会自动生成并且可以正常工作,但以防万一您需要做一些特殊的事情,请也包含它,或者如果无法让智能感知为此工作,请告诉我。可能是这样的:???

/// <summary>
/// MyFunc Summary
/// </summary>
/// <param name="name">Name description</param>
/// <param name="event1_id">ID for Event 1</param>
/// <param name="event1_value">Value for Event 1</param>
/// ...
/// <param name="eventN_id">ID for Event N</param>
/// <param name="eventN_value">Value for Event N</param>
/// <returns>return description</returns>

我会通过创建类型特征来解决这个问题。我的第一次尝试:

#include <iostream>
#include <type_traits>

namespace {
    template <typename FIRST_EXPECTED, typename SECOND_EXPECTED,
              typename FIRST_ACTUAL,   typename SECOND_ACTUAL,
              typename ...Ts>
    struct repeating_pair {
        static constexpr bool value = repeating_pair<FIRST_EXPECTED, SECOND_EXPECTED,
                                                     FIRST_ACTUAL, SECOND_ACTUAL>::value &&
                                      repeating_pair<FIRST_EXPECTED, SECOND_EXPECTED,
                                                     Ts...>::value;
    };

    template <typename FIRST_EXPECTED, typename SECOND_EXPECTED,
              typename FIRST_ACTUAL,   typename SECOND_ACTUAL>
    struct repeating_pair<FIRST_EXPECTED, SECOND_EXPECTED, FIRST_ACTUAL, SECOND_ACTUAL> {
        static constexpr bool value = std::is_same_v<FIRST_ACTUAL, FIRST_EXPECTED> &&
                                      std::is_same_v<SECOND_ACTUAL, SECOND_EXPECTED>;
    };

}

int main() {
    std::cout << repeating_pair<int, double, int, double>::value << '\n'
              << repeating_pair<int, double, int, float>::value << '\n'
              << repeating_pair<int, double, int, double, int, double>::value << '\n'
              << repeating_pair<int, double, int, double, int, float>::value << '\n';
    return 0;
}

这会给你一个 compile-time 检查你是否有重复的类型,你可以在 MyFunc.

中利用它
template <typename FIRST, typename SECOND, typename ...Ts>
void MyFunc(std::string stringVar, FIRST intVar1, SECOND doubleVar1, Ts ...ts) {
    static_assert(repeating_pair<int, double, FIRST, SECOND, Ts...>::value);
    // whatever your code does
}

如果我明白你要做什么,你可以编写以下函数:

template<typename ...Ts>
void MyFunc(std::string Var, Ts ...ts)
{
    // simple structure to store each pair of arguments
    struct Arg { int i; double d; }; 

    // checks narrowing conversions, 
    // and incorrect type/number of arguments
    std::array<Arg, sizeof...(Ts) / 2> arr { ts... };   

    // ensures at least one int and double argument
    static_assert(std::size(arr) > 1);  

    // ...
}

这是一个demo