如何将具有不同第二类型的 `std::pair` 的可变数量传递给函数

iam*_*ind 5 c++ templates variadic-templates c++11 std-pair

抱歉,由于问题的复杂性,无法解释标题中的主要 Q。
需要将各种类型的std::pairs 传递给如下所示的方法:

foo({1, 1} , {2, 2.2}, {3, "3"});  // 'first' is always `int`
Run Code Online (Sandbox Code Playgroud)

但是,我无法弄清楚如何定义使用可变参数模板的语法foo()

这更像是一种装饰性的变化,其目的是避免样板代码。因此排除以下建议:

template<typename... Args>
void foo (Args&&... args) { ... }

template<typename T> using pair = std::pair<int, T>;
foo(pair<int>{1, 1} , pair<double>{2, 2.2}, pair<std::string>{3, "3"});
Run Code Online (Sandbox Code Playgroud)

对于任何有兴趣的人,我将如何处理各种pairs。将在所有args...(使用数组技巧)上调用重载函数,并且所有second值将转换为std::string. 对于那些不知道著名的数组技巧的人:

const string array[] = { MyFunc(std::forward<Pairs>(pairs)) ... };
Run Code Online (Sandbox Code Playgroud)

类似(但不重复)的问题:Passing multiple std::pair to variadic template constructor using { }, { }

rah*_*ma1 5

您可以简单地使用这个签名:

template<typename... Args>
void foo (std::pair<int, Args> ...args) { /*...*/}
Run Code Online (Sandbox Code Playgroud)

或者

template <typename ...Args> using pair = std::pair<int, Args...>;
Run Code Online (Sandbox Code Playgroud)

编辑:如前所述,问题是关于在不提供模板参数的情况下构造 std::pair 并将对的第二部分转换为字符串。通过重载 () 运算符,我们可以写:

#include <iostream>
#include <vector>
#include <sstream>

struct Function{
    template <typename T>
    Function& operator()(int a, T b){
        ss << b;
        list.push_back(ss.str());
        ss.str("");
        return *this;
    }

    std::vector<std::string> get_string(){
        return list;
    }
    std::vector<std::string> list;
    std::stringstream ss;
};
int main(){
    Function foo;
    for(auto& s: foo(1, 3.0)(2,"foo")(3, 5.0f).get_string())
    {
        std::cout << s << std::endl;
    }
} 
Run Code Online (Sandbox Code Playgroud)

  • 这不是问题,OP想要调用`foo({...}, {...}, {...}...)`而不是`pair&lt;int&gt;{},pair&lt;double &gt;{}` 等.. (2认同)

max*_*x66 5

如果你的意图是foo()这样调用

foo({1, 1} , {2, 2.2}, {3, "3"}); 
Run Code Online (Sandbox Code Playgroud)

使用带值的花括号而不是显式的std::pair<int, int>{1,1}, std::pair<int, double>{1, 2.2}, ..........我认为这是不可能的。

如果你可以放弃大括号,那么用foo()这种方式调用,

foo(1, 1 , 2, 2.2, 3, "3"); 
Run Code Online (Sandbox Code Playgroud)

并在里面构建对foo(),你可以做类似的事情

#include <string>
#include <utility>

void foo ()
 { 
   // do nothing ?
 }

template <typename T2, typename ... Ts>
void foo (int v1, const T2 & v2, const Ts & ... vs)
 { 
   std::pair<int, T2>  p { v1, v2 };

   // do something with p

   foo(vs...);
 }

int main()
 {
   foo(1, 1, 1, 2.2, 1, std::string("3"));

   return 0;
 }
Run Code Online (Sandbox Code Playgroud)

但是,坦率地说,我不喜欢这个解决方案,因为不清楚哪对正在调用,所以我认为这是使用foo()rahnema1 的解决方案调用的更好方法foo()make_pair()

foo(std::make_pair(1, 1), std::make_pair(1, 2.2),
    std::make_pair(1, std::string("3")));
Run Code Online (Sandbox Code Playgroud)