我正在创建一种机制,允许用户使用装饰器模式从基本构建块中形成任意复杂的函数.这可以很好地实现功能,但我不喜欢它涉及大量虚拟调用的事实,特别是当嵌套深度变大时.它让我担心,因为复杂的功能可能经常调用(> 100.000倍).
为了避免这个问题,我尝试将装饰器方案转换为std::function一次完成(to_function()在SSCCE中为cfr.).所有内部函数调用都是在构建期间连线的std::function.我认为这比原始装饰器方案评估更快,因为在std::function版本中不需要执行虚拟查找.
唉,基准测试证明我错了:装饰器方案实际上比std::function我建造的更快.所以现在我想知道为什么.也许我的测试设置有问题,因为我只使用两个简单的基本函数,这意味着可以缓存vtable查找?
我使用的代码包含在下面,不幸的是它很长.
// sscce.cpp
#include <iostream>
#include <vector>
#include <memory>
#include <functional>
#include <random>
/**
* Base class for Pipeline scheme (implemented via decorators)
*/
class Pipeline {
protected:
std::unique_ptr<Pipeline> wrappee;
Pipeline(std::unique_ptr<Pipeline> wrap)
:wrappee(std::move(wrap)){}
Pipeline():wrappee(nullptr){}
public:
typedef std::function<double(double)> FnSig;
double operator()(double input) const{
if(wrappee.get()) input=wrappee->operator()(input);
return process(input);
}
virtual double process(double input) const=0;
virtual ~Pipeline(){}
// Returns a std::function which contains the entire Pipeline …Run Code Online (Sandbox Code Playgroud) 返回值优化(RVO)是一种涉及复制省略的优化技术,它消除了在某些情况下为保存函数返回值而创建的临时对象.我一般都了解RVO的好处,但我有几个问题.
该标准在本工作草案的第12段第32段(强调我的)中说明了以下内容.
当满足某些条件时,允许实现省略类对象的复制/移动构造,即使该对象的复制/移动构造函数和/或析构函数具有副作用.在这种情况下,实现将省略的复制/移动操作的源和目标视为仅仅两种不同的引用同一对象的方式,并且该对象的销毁发生在两个对象的后期时间.没有优化就被破坏了.
然后,当实现可以执行此优化时,它会列出许多条件.
关于这种潜在的优化,我有几个问题:
我习惯于约束优化,以至于它们无法改变可观察的行为.此限制似乎不适用于RVO.我是否需要担心标准中提到的副作用?是否存在可能导致问题的角落案例?
作为程序员,我需要做什么(或不做)才能执行此优化?例如,以下是否禁止使用复制省略(由于move):
std::vector<double> foo(int bar){
std::vector<double> quux(bar,0);
return std::move(quux);
}
Run Code Online (Sandbox Code Playgroud)
我将此作为一个新问题发布,因为我提到的具体问题在其他相关问题中没有直接回答.
我正在寻找一种直观和可扩展的方法来实现c ++中给定基类的子类的工厂.我想在库中提供这样的工厂函数.棘手的部分是我希望工厂也为用户定义的子类工作(例如,让库的工厂函数构建不同的子类,具体取决于链接到它的模块).目标是为下游开发人员使用工厂带来最小的负担/困惑.
我想要做的一个例子是:给定a std::istream,构造并返回与内容匹配的子类的对象,如果没有找到匹配则返回空指针.全球工厂的签名如下:
Base* Factory(std::istream &is){ ... };
Run Code Online (Sandbox Code Playgroud)
我熟悉原型工厂,但我更愿意避免制作/存储原型对象.这里发布了一个相关的问题:java:使用工厂允许最大的灵活性/可扩展性.
我目前不是在寻找c ++ 11特定的解决方案,但如果它们更优雅,我会很乐意了解这些.
我提出了一个工作解决方案,我相信它相当优雅,我将作为答案发布.我可以想象这个问题相当普遍,所以我想知道是否有人知道更好的方法.
编辑:似乎有些澄清是为了......
这个想法是让工厂构造派生类的对象,而不包含决定哪一个的逻辑.更糟糕的是,工厂方法最终将作为库的一部分,派生类可以在插件中定义.
派生类必须能够根据提供的输入(例如输入文件)自行决定它们是否适合构造.正如几个人所建议的那样,这个决定可以作为工厂可以使用的谓词来实现(顺便提一下,很好的建议!).
我终于开始阅读c ++ 11了,我不明白为什么需要trailing-return-types.
我遇到了以下示例,用于突出显示问题:
template<class Lhs, class Rhs>
decltype(lhs+rhs) adding_func(const Lhs &lhs, const Rhs &rhs) {return lhs + rhs;}
Run Code Online (Sandbox Code Playgroud)
这个例子是非法的,因为decltype(lhs+rhs)没有工作,因为标识符lhs和rhs仅解析阶段后有效.
我想我的问题是关于decltype类型解析的时间.如果我没有弄错,关键字decltype用于在编译时确定表达式的类型.
decltype在完成所有解析之后,我没有看到执行类型解析的缺点(这对于上面的示例可以正常工作).我相信这将是解决问题的一种更简单的方法......
相反,C++ 11标准提供了trailing-return-types:
template<class Lhs, class Rhs>
auto adding_func(const Lhs &lhs, const Rhs &rhs) -> decltype(lhs+rhs) {return lhs + rhs;}
Run Code Online (Sandbox Code Playgroud)
我毫不怀疑我遗漏了一些东西,因为我没有看到其他使用trailing-return-types.我的推理中的缺陷在哪里?
trailing-return-types对我来说似乎是一个过于复杂的解决方案,因为decltype在解析完整的函数体之后具有类型解析也可以正常工作?
我的Eclipse中的拼写检查器今天顽皮地建议亵渎(cfr.image).

我该怎样才能防止它变得粗鲁?
我刚开始学习Haskell,我似乎找不到有条件地创建列表的好方法.
基本上,我想要的是列表理解与if/else但没有else部分.我确信这是可能的,我想我只是在google搜索任务中使用了错误的关键字.
Python中我想要Haskellize的一个非常愚蠢的例子:
[x for x in range(11) if x > 5]
Run Code Online (Sandbox Code Playgroud)
在Haskell中,据我所知,我们不能else像在Python示例中那样省略块.我该怎么做这样的事情?什么都不存在,我可以添加到else列表理解中的-block,如下所示:
[if x > 5 then x else Nothing | x <- [0..10]]
Run Code Online (Sandbox Code Playgroud)
我实际上在Haskell中遇到了Nothing,尽管我还没弄明白.它当然似乎没有做我希望的.基本上我不希望else我的列表理解,但如果它是一个必要的邪恶我想在else块中插入任何东西.
我可以想到一堆黑客可以非常低效地获得类似的功能:
filter 创建后的列表,例如 filter (>5) [0..10]concat它们,例如concat [if x > 5 then [x] else [] | x <- [0..10]]这些想法都显得实在难看,虽然.
在实践中,我不想创建具有这些微不足道条件的条件列表.
我目前正在将我对C++的知识更新为新标准.它让我觉得自己像个小孩子才能拥有最棒的玩具:我想一直玩它,但我不想因为它而失去我的朋友.
我参与了一些开源项目,其中一些新功能非常有用,所以我非常热衷于使用它们.我的问题是有多少用户可以编译C++ 11代码,例如,普通公众中C++ 11-complete编译器的采用率是多少?有没有人有相关信息?
我知道gcc 4.8.1和clang 3.3是完整的C++ 11功能,但我不知道有多少人真正使用了最新的编译器.我知道大多数codemonkeys肯定会这样做,但是普通的开源用户呢?拍摄潜在用户并告诉他们更新他们的编译器并不是一个真正的选择.
我知道这个问题可能因为与这些问题相似而受到批评/关闭:
我想指出现在情况有所不同,因为我们正在谈论一个实际批准的标准.我相信,在编程实践中,了解其采用率非常重要.
我有一个模板化的类,我想根据模板参数启用不同的构造函数.具体来说,我想std::is_compound用作标准.
// bla.cpp
#include <type_traits>
#include <vector>
template <typename T>
class Foo{
double bar;
public:
template<typename U=T,
class = typename std::enable_if<std::is_compound<U>::value>::type
>
Foo(typename T::value_type& b):bar(b){}
template<typename U=T,
class = typename std::enable_if<!std::is_compound<U>::value>::type
>
Foo(T b):bar(b){}
};
int main(){
double d=1.0;
Foo<std::vector<double>> f2(d); // works
Foo<double> f1(d); // compiler error
}
Run Code Online (Sandbox Code Playgroud)
我收到以下编译错误:
g ++ -std = gnu ++ 11 bla.cpp
bla.cpp: In instantiation of ‘class
Foo<double>’: bla.cpp:22:18: required from here bla.cpp:11:2: error:
‘double’ is not a class, struct, or …Run Code Online (Sandbox Code Playgroud) 我std::bind在代码的各个地方使用时遇到了很多麻烦.有时候它会起作用,有时却不起作用,所以我认为我做的事情根本就是错误的.
据我了解,以下基本用法std::bind应该可以正常工作:
#include <functional>
int foo(int a, int b){ return a+b; }
int main(){
using namespace std::placeholders;
// works
auto bar_auto=std::bind(foo,1,_2);
// compile error
std::function<int(int)> bar_fun=std::bind(foo,1,_2);
int quux=1;
// compile error
std::function<int(int)> bar_fun_lvalue=std::bind(foo,quux,_2);
}
Run Code Online (Sandbox Code Playgroud)
毫无疑问的类型bar_auto是std::function<int(int)>(类型foo1个int参数绑定),所以为什么bar_fun编译失败?我包括bar_fun_lvalue因为一些谷歌搜索向我显示rvalues曾经是有问题的.但这并没有解决任何问题.
它类似于这个bug,但是它太旧了我不认为它是相关的.
gcc的输出不是特别有启发性:
在bindnew.cpp中包含的文件中:1:0:/usr/include/c++/4.7/functional:在'static _Res std :: _ Function_handler <_Res(_ArgTypes ...),_Functor> :: _ M_invoke(const std)的实例化中:: _ Any_data&,_ ArgTypes ...)[with _Res = int; _Functor = std :: …