考虑以下代码:
template<class F>
void foo1(F f) { f(); }
template<class F>
void foo2(F const& f) { f(); }
template<class F>
void foo3(F&& f) { f(); }
Run Code Online (Sandbox Code Playgroud)
foo我应该使用哪个版本?foo1这是我在"野外"看到的最多,但我担心它可能会引入我不想要的副本.我有一个很复杂的自定义仿函数,所以我想避免这种情况.目前我倾向于foo3(因为foo2不允许变异的算子),但我不确定其含义.
我的目标是C++ 11.
我有一组shared_ptr,我想将remove_copy_if与谓词的自定义函数对象一起使用.我不知道"最好"的方式.现在,我有这个工作:
class CellInCol : public std::unary_function<const std::shared_ptr<Cell>,
bool>
{
public:
CellInCol( size_t col ) : _col( col ) {}
bool operator() ( const std::shared_ptr<Cell> &a ) const
{
return ( a->GetX() == _col );
}
private:
size_t _col;
};
typedef std::set<std::shared_ptr<Cell>, CellSorter> Container;
Container _grid;
// initialization omitted...
Puzzle::Container Puzzle::GetCol( size_t c )
{
Cell::Validate( c, 1, 9 );
Container col;
std::remove_copy_if( _grid.begin(), _grid.end(),
std::inserter( col, col.begin() ),
std::not1( CellInCol( c ) ) );
return col;
}
Run Code Online (Sandbox Code Playgroud)
我决定对shared_ptr执行const引用,因为该对象不会保留指针,这似乎比shared_ptr的额外副本更有效.
看起来对对象进行const引用似乎更好,但是我无法编译它.我把它改成了这个,但没有运气:
class …Run Code Online (Sandbox Code Playgroud) 我想在集合中存储具有类似签名的函数,以执行以下操作:
f(vector<Order>& orders, vector<Function>& functions) {
foreach(process_orders in functions) process_orders(orders);
}
Run Code Online (Sandbox Code Playgroud)
我想到了函数指针:
void GiveCoolOrdersToBob(Order);
void GiveStupidOrdersToJohn(Order);
typedef void (*Function)(Order);
vector<Function> functions;
functions.push_back(&GiveStupidOrdersToJohn);
functions.push_back(&GiveCoolOrdersToBob);
Run Code Online (Sandbox Code Playgroud)
或多态函数对象:
struct IOrderFunction {
virtual void operator()(Order) = 0;
}
struct GiveCoolOrdersToBob : IOrderFunction {
...
}
struct GiveStupidOrdersToJohn : IOrderFunction {
...
}
vector<IOrderFunction*> functions;
functions.push_back(new GiveStupidOrdersToJohn());
functions.push_back(new GiveCoolOrdersToBob());
Run Code Online (Sandbox Code Playgroud) 当我声明一个变量时function<void(const Foo&)>,编译器仍然允许我分配一个接受值的lambda:
function<void(const Foo&)> handler;
handler = [](Foo f){};
Run Code Online (Sandbox Code Playgroud)
(cfr.也是http://cpp.sh/5dsp)
因此,当调用处理程序时,将创建一个副本.标准的哪个部分允许这个?有没有办法我可以标记客户端代码,这将是一个问题(一些static_assert的排序?)?
我想使用std :: tm()作为std :: map-container的键.但是当我尝试编译它时,我得到了很多(10)错误.
例如:
1.
错误C2784:'bool std :: operator <(const std :: basic_string <_Elem,_Traits,_Alloc>&,const _Elem*)':无法推断'const std :: basic_string <_Elem,_Traits,_Alloc>的模板参数&'from'const tm'c:\ program files(x86)\ microsoft visual studio 10.0\vc\include\xfunctional 125
2.
错误C2784:'bool std :: operator <(const _Elem*,const std :: basic_string <_Elem,_Traits,_Alloc>&)':无法从'const tm'c:\中推断'const _Elem*'的模板参数程序文件(x86)\ microsoft visual studio 10.0\vc\include\xfunctional 125
3.
错误C2784:'bool std :: operator <(const std :: vector <_Ty,_Ax>&,const std :: vector <_Ty,_Ax>&)':无法推断'const std :: vector <的模板参数_Ty,_Ax>&'from'const tm'c:\ program files(x86)\ microsoft visual studio 10.0\vc\include\xfunctional 125
这一切是否意味着,我"只是"必须创建一个比较两个std :: tm的函数对象,因为没有为此定义的标准比较?还是有另一招?(或者对我来说甚至可能不可能?^^)
码:
#include <map>
#include …Run Code Online (Sandbox Code Playgroud) 我正在设计一种机制,它将按顺序执行一组一元函数对象.这些函数对象在运行时分配,问题是:这些函数对象的参数类型不同.
我想做的是这样的:
class command_sequence {
private:
/* some kind of container */
public:
void add( FUNC_OBJ &func, PARAM val );
void run(void);
};
class check_temperature {
public:
void operator() (int celsius) {
if(celsius > 26) {
cooler.switch_on();
}
}
};
class log_usage {
public:
void operator() (std::string username) {
username.append(" logged in");
syslog(LOG_NOTICE,username.c_str());
}
};
command_sequence sequence;
log_usage logger;
check_temperature checker;
sequence.add(logger, std::string("administrator"));
sequence.add(checker, lobbyMeter.read_temperature());
sequence.add(logger, std::string("lecture"));
sequence.add(checker, classroomMeter.read_temperature());
sequence.run();
Run Code Online (Sandbox Code Playgroud)
如果我正在编写C代码,我别无选择只能将void*作为参数的回调函数指针.但我现在正在使用C++,应该有一种优雅的方式来处理它.
我现在能想到的最好方法是声明一个虚拟继承自抽象包装类的模板类:
class command_sequence {
private:
class runner {
public: …Run Code Online (Sandbox Code Playgroud) 有人可以帮助我理解为什么下面的代码会导致错误吗?
class A
{
public:
float& operator()()
{
return _f;
}
private:
float _f = 1;
} a;
auto& foo()
{
std::function<float()> func = a;
return func();
}
int main()
{
std::cout << foo() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
错误:
error: non-const lvalue reference to type 'float' cannot bind to a temporary of type 'float'
return func();
^~~~~~
1 error generated.
Run Code Online (Sandbox Code Playgroud)
在这里,operator()我返回一个参考_f,因此,我认为func()这不是暂时的.如果有人帮助我理解会很棒.
我有一个如下的脚本。目的是采用不同的过滤方法来过滤列表。
这是代码。
2
3 class list_filter {
4 has @.my_list = (1..20);
5
6 method filter($l) { return True; }
7
8 # filter method
9 method filter_lt_10($l) {
10 if ($l > 10) { return False; }
11 return True;
12 }
13
14 # filter method
15 method filter_gt_10($l) {
16 if ($l < 10) { return False; }
17 return True;
18 }
19
20 # expecting a list of (1..10) to be the output here
21 …Run Code Online (Sandbox Code Playgroud) 我正在实现一个具有多个构造函数的类,它是围绕 IndexedWidgetBuilder(一个函数对象)在内部构建的
typedef IndexedWidgetBuilder = Widget Function(BuildContext context, int index);
Run Code Online (Sandbox Code Playgroud)
现在,调用它的构造函数之一MyWidget.list将接收一个列表myList并从中创建 IndexedWidgetBuilder myBuilder:
IndexedWidgetBuilder myBuilder
= (BuildContext context, int index) => list[index % list.length];
Run Code Online (Sandbox Code Playgroud)
虽然这个代码片段单独工作得很好,但我无法在构造函数的初始化列表中使用它。一个最小的工作示例读取
class MyApp {
// Default constructor goes here
MyApp.list(List<int> myList) :
myBuilder = (BuildContext context, int index) => list[index % list.length];
final IndexedWidgetBuilder myBuilder;
}
Run Code Online (Sandbox Code Playgroud)
在 Android Studio 中,此代码段会产生错误:
初始化器类型“Type”不能分配给字段类型“(BuildContext, int)?小部件'。
我在 google 上没有找到任何相关内容,语言文档也没有提供有用的信息。删除final关键字并将所有内容移动到构造函数的代码块中将是一种解决方案,尽管我只会考虑作为最后的手段。
注意:这不是直接的颤振问题,因为它发生在每个函数对象中。
function-object ×10
c++ ×8
c++11 ×1
c++14 ×1
coercion ×1
constructor ×1
covariance ×1
dart ×1
delegates ×1
flutter ×1
functor ×1
key ×1
map ×1
perl6 ×1
shared-ptr ×1
std-function ×1
templates ×1