繁体   English   中英

如何将functor用作类模板中的成员?

[英]How to use functor as a member in class template?

我试图在类模板中使用仿函数作为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
        ^

有可能这样做吗? 怎么解决?

您可以将其设置为静态并在类范围外初始化它,或者在构造函数中初始化它。 在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>() };

在你的情况下,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>(); <-- **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 declration移动到运算符,即:

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 <>,std :: greater <>以及更多其他仿函数模板关键字移动到运算符声明中,而不是结构声明,这有助于更通用的比较。

编辑2:您可以使用以下技术:

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
}

在非静态数据成员初始值设定项中使用std :: function的不同方法

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

补充问题

我试图找出变量brace-or-equal-initializer和非静态数据成员brace-or-equal-initializer之间的差异。 我一无所获。

有什么区别

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

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

当ENABLE_CONVERSION为零时?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM