【问题标题】:c++ varargs/variadic function with two types of arguments that repeat together (alternating)c++ varargs/variadic 函数,两种类型的参数一起重复(交替)
【发布时间】:2020-10-14 15:39:52
【问题描述】:

我可以找到一些示例,说明如何使用一种重复的类型(如 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>

【问题讨论】:

  • 更简单的方法是使用 pair/struct 来分组 ID 和值。然后可能是vector/initializer_list
  • 智能感知不处理 SFINAE,因此硬编码重载可能是文档/智能感知的一个选项。然后您仍然可以转发到可变参数解决方案。
  • 我不清楚你在问什么。你能展示这个函数的示例实现吗?另外,您所说的“让文档告诉您您使用的是哪种 arg 类型。” 是什么意思?

标签: c++ variadic-templates variadic-functions


【解决方案1】:

如果我理解您要做什么,您可以编写以下函数:

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

【讨论】:

    【解决方案2】:

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

    #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;
    }
    

    这会给你一个编译时检查你有重复类型,你可以在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
    }
    

    【讨论】:

      猜你喜欢
      • 2023-02-07
      • 2019-10-20
      • 2013-06-06
      • 2015-12-27
      • 2016-09-11
      • 1970-01-01
      • 1970-01-01
      • 2014-03-15
      相关资源
      最近更新 更多