c++ 变量模板,获取函数参数值

egdjgwm8  于 2023-01-15  发布在  其他
关注(0)|答案(3)|浏览(111)

我的问题如下:我有一个类声明如下:

template<typename ReturnType, typename... Args>
class API
{
    ReturnType operator()(Args... args)
    {
       // Get argument 0
       // Get argument 1
    }
};

我需要一个一个地得到参数,到目前为止,我想到的唯一方法(但我不能让它工作)是使用std::get,如下所示:

std::get<0>(args);

当然,这会导致很多错误。我是可变参数模板的新手(也是C++11的新手),所以在这一点上我很困惑。
我怎样才能把这些论据一个一个地弄清楚呢?如有任何帮助,我将不胜感激。

wfsdck30

wfsdck301#

捕获临时元组(Live at Coliru)中的参数:

ReturnType operator()(Args... args)
{
   static_assert(sizeof...(args) >= 3, "Uh-oh, too few args.");
   // Capture args in a tuple
   auto&& t = std::forward_as_tuple(args...);
   // Get argument 0
   std::cout << std::get<0>(t) << '\n';
   // Get argument 1
   std::cout << std::get<1>(t) << '\n';
   // Get argument 2
   std::cout << std::get<2>(t) << '\n';
}

std::forward_as_tuple使用完全转发来捕获对args的引用,因此不应存在复制。

hmae6n7t

hmae6n7t2#

可以使用递归。
下面是一个例子:

#include <iostream>

template<typename ReturnType>
class API {
public:
    template<typename Arg>
    ReturnType operator()(Arg&& arg) {
        // do something with arg
        return (ReturnType) arg;
    }

    template<typename Head, typename... Tail>
     ReturnType operator()(Head&& head, Tail&&... tail) {
        // do something with return values
        auto temp = operator()(std::forward<Head>(head));
        return temp + operator()(std::forward<Tail>(tail)...);
    }
};

int main() {
    API<int> api;
    auto foo = api(1, 2l, 2.0f);
    std::cout << foo;
    return 0;
}
watbbzwu

watbbzwu3#

一些辅助模板可以帮你做到这一点,我不知道stl中有哪个模板可以直接做到这一点,但我还是喜欢使用我自己的模板:

namespace Internal {
template <size_t Pos, typename Arg, typename... Args>
struct Unpacker {
    static auto unpack(Arg&&, Args&&... args) {
        return Unpacker<Pos - 1, Args...>::unpack(std::forward<Args>(args)...);
    }
};
template <typename Arg, typename... Args>
struct Unpacker<0, Arg, Args...> {
    static auto unpack(Arg&& arg, Args&&...) { return std::forward<Arg>(arg); }
};
} // Internal
template <size_t Pos, typename... Args>
auto unpack(Args&&... args) {
    return Internal::Unpacker<Pos, Args...>::unpack(std::forward<Args>(args)...);
}

然后,您可以像这样使用它:

auto unpacked0 = unpack<0>(1, "orange", 3.3f, "pie");
auto unpacked1 = unpack<1>(1, "orange", 3.3f, "pie");
auto unpacked2 = unpack<2>(1, "orange", 3.3f, "pie");
auto unpacked3 = unpack<3>(1, "orange", 3.3f, "pie");
// Will not compile, because there are only 4 arguments
// auto unpacked4 = unpack<4>(1, "orange", 3.3f, "pie");
fmt::print("{} {} {} {}\n", unpacked0, unpacked1, unpacked2, unpacked3);

或者在您的情况下:

template<typename ReturnType, typename... Args>
class API {
    ReturnType operator()(Args&&... args) {
       // Get argument 0
       auto& arg0 = unpack<0>(args...);
       // Get argument 1
       auto& arg1 = unpack<1>(args...);
    }
};

相关问题