如何在类模板中使用函子作为成员

How to use functor as a member in class template?

本文关键字:成员      更新时间:2023-10-16

我试图将函数用作类模板中的 std::function对象。下面是我到目前为止所做的。

//! the functor class template
template<typename T>
struct func
{
    void operator ()(T t)
    {
        std::cout << t << "n";
    }
};
//! the class template that holds a std::function object as a member
template<typename T>
struct Foo
{
    std::function<void(T)> bar = func<T>();
};

int main()
{
    Foo<int> foo;
    return 0;
}

有人抱怨

error: conversion from 'func<int>' to non-scalar type 'std::function<void(int)>' requested
 struct Foo
        ^

有可能这样做吗?如何修复它?

您可以使其静态并在class-scope之外进行初始化,也可以在构造函数中初始化它。在GCC 4.7.2。

上测试
template<typename T>                                                                                
struct Foo                                                                                          
{                                                                                                   
    static std::function<void(T)> bar;                                                                 
};                                                                                                  
template <typename T>                                                                               
std::function<void(T)> Foo<T>::bar = func<T>(); 

编辑

在C 11中,您也可以使用支撑仪:

std::function<void(T)> bar { func<T>() };

在非静态数据成员initializer

中使用std ::功能的不同方法
#include <functional>
#include <iostream>
#define ENABLE_CONVERSION 1
template<typename T>
struct func
{
    void operator ()(T t)
    {
        std::cout << "Function: " << t << "n";
    }
    #if ENABLE_CONVERSION
    // FIX: error: conversion from ‘func<int>’ to non-scalar type
    //      ‘std::function<void(int)>’ requested
    operator std::function<void(T)> () { return std::function<void(T)>(*this); }
    #endif
};
template<typename T>
struct Foo
{
    std::function<void(T)> bar0 = std::function<void(T)>(func<T>());
    std::function<void(T)> bar1{func<T>()};
    // Error without ENABLE_CONVERSION
    std::function<void(T)> bar2 = func<T>();
    static std::function<void(T)> bar3;
    void operator() () {
        bar0(0);
        bar1(1);
        bar2(2);
        bar3(3);
    }
};
template<typename T>
std::function<void(T)> Foo<T>::bar3 = func<T>();
template<typename T>
void goo() {
    // This compiles without ENABLE_CONVERSION:
    // What is the difference to non-static data member initializers ?
    std::function<void(T)> g = func<T>();
    g(4);
}
int main()
{
    Foo<int> foo;
    foo();
    goo<int>();
    return 0;
}

其他问题

我试图找到可变的支架或平等限制器之间的差异以及非静态数据成员支架或平等限制器。我什么也没找到。

有什么区别
std::function<void(T)> bar2 = func<T>();

std::function<void(T)> g = func<T>();

当enable_conversion为零时?

在您的情况下std ::函数是可选的,请使用直接函数本身。

//! the functor class template
template<typename T>
struct func
{
    void operator ()(T t)
    {
        std::cout << t << "n";
    }
};
//! the class template that holds a std::function object as a member
template<typename T>
struct Foo
{
    //std::function<void(T)> bar = func<T>(); <-- **removed, because std::function isn't cheap as func<T>**.
    func<T> bar;//default initialized itself.
};

int main()
{
    Foo<int> foo;
    foo.bar(24);//prints 24.
    return 0;
}

编辑: 在常见的情况下,将模板从struct声明移动到操作员,即:

struct func
{
   template< typename T >
   void operator()(T t ) const { std::cout << t << 'n'; }
};
struct Foo
{
    func m_func;
};
int main(){
   Foo f;
   f.m_func(24); // prints 24
   f.m_func("hello world"); // prints "hello world"
   f.m_func(3.143); // prints 3.143
   // and etc.,
};

在C 14中,std :: Less&lt;>,std :: greem&lt;>以及更多其他函子模板关键字移至运算符声明,而不是struct声明,而不是struct声明,这是帮助更通用的比较。

edit2:您可以使用以下技术:

struct func{  
  template< typename T > void operator()(T t) const{ std::cout << t << 'n';} 
};
template< typename T, typename Functor> // Functor as template
struct Foo
{
    Functor m_Functor; //--> functor member
    T       m_Data; // or something else.
};
// create `makeFoo`  for auto deduced functor type.
template< typename T, typename Functor>
Foo<T,Functor>  makeFoo(Functor f, T t ) { return {f,t}; }
int print(int i, int j){ std::cout << i+j << 'n' ;}
int main()
{
    auto foo = makeFoo(24, func{} );
    // use foo
    auto foo2 = makeFoo("hello", std::bind(print, 2, _1) ); 
   // use foo2
}