我试图在类模板中使用仿函数作为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
^
有可能这样做吗?如何解决?
答案 0 :(得分:2)
您可以将其设置为静态并在类范围外初始化它,或者在构造函数中初始化它。在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>() };
答案 1 :(得分:1)
在你的情况下,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&lt;&gt ;,std :: greater&lt;&gt;和更多其他仿函数模板关键字移动到运算符声明,而不是结构声明,这有助于更多的通用比较。
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
}
答案 2 :(得分:1)
在非静态数据成员初始值设定项中使用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为零时?