c++ - 模板类的可变成员函数

标签 c++ templates c++11

我遇到了一个问题,我正在尝试使用特定类型的参数包创建可变参数成员函数。

template <typename T>
struct A
{
    using result_type = T;

    T operator()(T a, T b)
    {
        return a+b;   
    }
};

template <typename Functor>
struct B
{
    using T = typename Functor::result_type;

    T operator()(Functor &&f, T... args)
    {
        return f(args...);
    }
};

它的预期工作方式如下:

A<int> a;
B<A<int>> b;

int result = b(a, 2, 3); // should return 5

但是我得到以下错误:

error: type 'T' (aka 'typename Functor::result_type') of function parameter pack does not contain any unexpanded parameter packs
        T operator()(Functor &&f, T... args)
                                  ~^~~~~~~~

error: pack expansion does not contain any unexpanded parameter packs
            return f(args...);
                     ~~~~^

实现预期功能的正确方法是什么?

最佳答案

只有当函数是函数模板时才能使用参数包。

来自 http://en.cppreference.com/w/cpp/language/parameter_pack :

A template parameter pack is a template parameter that accepts zero or more template arguments (non-types, types, or templates). A function parameter pack is a function parameter that accepts zero or more function arguments.

A template with at least one parameter pack is called a variadic template.

 template <typename ... Args>
 T operator()(Functor&& f, Args... args)
 {
     return f(args...);
 }

此外,在上述函数中使用 && 仅当它是模板参数时才有意义。当您在参数上使用 && 而类型不是模板参数时,您不能使用:

 A<int> a;
 B<A<int>> b;
 int r = b(a, 2, 3);

但是,您可以使用

int r = b(std::move(a), 2, 3);

做出您的选择。保持参数类型不变并使用 std::move(a) 或更改函数以使用简单引用

 template <typename ... Args>
 T operator()(Functor& f, Args... args)
 {
     return f(args...);
 }

和使用

 int r = b(a, 2, 3);

更新

您可以使用辅助类来确保所有参数都是正确的类型。

template<typename ... Args> struct IsSame : public std::false_type {};

template<typename T> struct IsSame<T> : public std::true_type {};

template<typename T, typename ... Args> struct IsSame<T, T, Args...> : public std::true_type
{
   static const bool value = IsSame<T, Args ...>::value;
};

并使用:

template <typename ... Args>
T operator()(Functor&& f, Args... args)
{
   static_assert(IsSame<T, Args...>::value, "Invalid argument type");
   return f(args...);
}

这样,

A<int> a;
B<A<int>> b;
int r = b(std::move(a), 2, 3);

仍然有效但是

r = b(std::move(a), 2, 3.0);

失败。

我不知道在您的情况下是否需要对参数类型如此严格。如果需要,您有办法。

关于c++ - 模板类的可变成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32674839/

相关文章:

javascript - 是否可以在 C 上实现延迟(非严格)数组?

c++ - 通过 IP 地址检测服务​​器是否在本地运行

c++ - 静态单例?

c++ - 使用外部模板 (C++11)

c++ - 如何创建用于创建循环的新样式?

c++ - 使用 emplace_back 将元素添加到 vector 时,如何强制编译器使用默认构造函数?

c++,如何一次将几个简单的 vector 写入二进制文件

c++ - C/C++ MultiMap 库

c++ - 如何在 MFC 中映射错误消息框的帮助 ID?

C++ 静态而非动态多态性