我有一个std::vector指针Person对象,它们具有成员函数std::string getName() const.使用STL算法我想计算Person向量中getName()返回"Chad"的所有对象.
简单地遍历循环的行为将是:
int num_chads = 0;
for(std::vector<Person *>::const_iterator it = vec.begin(); it != vec.end(); ++it)
{
if((*it)->getName() == "Chad")
++num_chads;
}
Run Code Online (Sandbox Code Playgroud)
我想重做这个,所以它使用所有STL算法和仿函数等(使其更加面向功能).这是我认为我需要做的事情:
const int num_chads = std::count_if(vec.begin(), vec.end(),
std::bind1st(std::bind2nd(std::equal_to, mem_fun(Person::getName)), "Chad"));
Run Code Online (Sandbox Code Playgroud)
你可能会说这不起作用.首先,据我所知,你不能在binder1st/binder2nd对象上使用bind1st/bind2nd,因为它们是专门设计用的std::binary_functions.其次,更重要的是,我认为我没有使用正确的技术.我确实希望将其中一个参数绑定到"Chad",但是使用iterator参数我实际上只是想在调用绑定版本之前将迭代器值转换为字符串equals_to.
我认为使用Boost可以做到这一点,但是可能只使用核心C++ 03(即没有C++ 0x lambas!)?
编辑:任何人都可以提出一个不使用用户定义的谓词的例子(即只使用std工具包中提供的工具)?
编辑:虽然Matthieu的答案是关于如何在STL算法中使用仿函数的教科书答案,但Cubbi的答案来自我正在寻找的方法(尽管Mathieu在编辑问题之前确实回答了它以使其更具体,所以在那里道歉!).
我有一个函数,其中我有保持的字符串(例如一个容器vector<string>,set<string>,list<string>给定的开始迭代和结束迭代器),并且,经过迭代范围处理所述字符串.
目前该函数声明如下:
template< typename ContainerIter>
void ProcessStrings(ContainerIter begin, ContainerIter end);
Run Code Online (Sandbox Code Playgroud)
现在,这将接受任何符合实现operator*,前缀operator++和函数体中其他调用的隐式接口的类型.
我真正想做的是有一个像下面那样明确限制输入量的定义(伪代码警告):
template< typename Container<string>::iterator>
void ProcessStrings(Container<string>::iterator begin, Container<string>::iterator end);
Run Code Online (Sandbox Code Playgroud)
所以我可以这样使用它:
vector<string> str_vec;
list<string> str_list;
set<SomeOtherClass> so_set;
ProcessStrings(str_vec.begin(), str_vec.end()); // OK
ProcessStrings(str_list.begin(), str_list.end()); //OK
ProcessStrings(so_set.begin(), so_set.end()); // Error
Run Code Online (Sandbox Code Playgroud)
本质上,我想要做的是限制函数规范,使函数的用户明白它接受的内容,如果代码编译失败,他们会得到一条消息,他们使用了错误的参数类型而不是XXX类无法找到XXX函数的函数体.
我必须doubles从文件中加载一个数组,将每个元素乘以一个表中的值(不同元素的不同值),对它做一些工作,反转乘法(即除法),然后将数据保存回文件.
目前,我用两种不同的方法实现乘法和除法过程.现在幕后有一些额外的工作,但除了发生乘法/除法的特定陈述之外,其余代码是相同的.可以想象,通过这种方法,您必须非常小心地进行任何更改.周围的代码并不简单,因此它可以是手动编辑每个方法或将更改从一个方法复制到另一个方法并记住更改*和/运算符的情况.
经过太多的关闭调用之后,我厌倦了这个并且希望创建一个实现公共逻辑和两个包装函数的通用函数,它们将哪个运算符用作参数.
我最初的方法是使用函数指针:
void MultiplyData(double data)
{ TransformData(data, &(operator *)); }
void DivideData(double data)
{ TransformData(data, &(operator /)); }
void TransformData(double data, double (*func)(double op1, double op2))
{ /* Do stuff here... */ }
Run Code Online (Sandbox Code Playgroud)
但是,我不能将运算符作为指针传递(这是因为它是本机类型的运算符吗?),所以我尝试使用函数对象.最初我认为multiplies和dividesfunctor <functional>是理想的:
void MultiplyData(double data)
{
std::multiplies<double> multFunct;
TransformData(data, &multFunct);
}
void DivideData(double data)
{
std::divides<double> divFunct;
TransformData(data, &divFunct);
}
void TransformData(double data, std::binary_function<double, double, double> *funct)
{ /* Do stuff here... */ }
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我试图使用基类指针以多态方式传递函子.问题是std::binary_function没有声明operator() …
我有一个控制台应用程序,用于SetConsoleCtrlHandler设置处理和处理的处理程序CTRL_CLOSE_EVENT.处理程序简单的返回TRUE,这将导致一个对话框出现,并提示用户继续关闭或取消.
该软件在Windows XP SP3和Windows Web Server 2008 SP2上运行.
在XP中,当单击控制台窗口中的"X"时,我的控制处理程序被调用,并预期会出现提示.在Server 2008上关闭控制台窗口不会调用我的控制处理程序,应用程序将关闭而不会提示.
要检查控制处理程序是否正确设置,我已添加了一个案例CTRL_C_EVENT.我可以看到为Ctrl-C调用代码.
Server 2008中处理关闭事件的方式有什么不同吗?好像他们根本没有通过ctrl处理程序.
编辑:看一下MSDN页面SetConsoleCtrlHandler约我无法找到任何信息CTRL_CLOSE_EVENT不再在Vista和更高版本正在处理.
如果你正在使用Windows处理(HWND),而不是控制台CTRL事件,是有可能得到发送到控制台窗口中的关闭消息,并处理这个问题?
我有一个类定义数据库的历史提取:
class ExtractionConfiguration
{
string ExtractionName;
time ExtractionStartTime;
time ExtractionEndTime;
// Should these functions be static/non-static?
// The load/save path is a function of ExtractionName
void SaveConfigruation();
void LoadConfiguration();
}
Run Code Online (Sandbox Code Playgroud)
这些ExtractionConfiguration需要保存到磁盘/从磁盘加载.在静态/非静态方面组织保存/加载功能的最佳方法是什么?对我来说,很明显SaveConfiguration()应该是一个成员函数.但是使用LoadConfiguration(),调用更有意义
ExtractionConfiguration newExtraction;
newExtraction.LoadConfiguration();
Run Code Online (Sandbox Code Playgroud)
并有一个临时的空实例或使加载功能静态
static ExtractionConfiguration LoadConfiguration(string filename);
Run Code Online (Sandbox Code Playgroud)
然后打电话
ExtractionConfiguration newExtraction = ExtractionConfiguration::LoadConfiguration(filename);
Run Code Online (Sandbox Code Playgroud)
对我来说感觉更整洁,但打破了加载/保存机制的"对称性"(这是否是一个有意义/值得考虑的问题?).
我想要求'最好'的答案有点天真.我真的想要更好地理解这里涉及的问题.
PS这是我关于SO的第一个问题,所以如果我没有正确提出,请告诉我,我会尽力让问题更清晰.
看看这个用于实现Spirit解析器的示例,当我尝试编写类似的东西时,有些事情让我感到困惑.
语法(std::map<std::string, std::string>())的属性模板参数和规则的签名模板参数(例如qi::rule<Iterator, std::string()> key, value)包含括号.
namespace qi = boost::spirit::qi;
template <typename Iterator>
struct keys_and_values
: qi::grammar<Iterator, std::map<std::string, std::string>()> // <- parentheses here
{
keys_and_values()
: keys_and_values::base_type(query)
{
query = pair >> *((qi::lit(';') | '&') >> pair);
pair = key >> -('=' >> value);
key = qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9");
value = +qi::char_("a-zA-Z_0-9");
}
qi::rule<Iterator, std::map<std::string, std::string>()> query; // <- parentheses here
qi::rule<Iterator, std::pair<std::string, std::string>()> pair; // <- parentheses here
qi::rule<Iterator, std::string()> key, …Run Code Online (Sandbox Code Playgroud) mvtnormdmvnorm R 包中函数的签名是:
dmvnorm(x, mean = rep(0, p), sigma = diag(p), log = FALSE)
Run Code Online (Sandbox Code Playgroud)
在描述中,x参数是分位数的向量或矩阵。如果提供了均值和协方差矩阵,那么这应该足以定义分布,那么为什么需要四分位数信息呢?
二维分布的用法示例:
cbind(map_data$X, map_data$Y)
x_mean <- mean(map_data$X)
y_mean <- mean(map_data$Y)
covar <- var(cbind(map_data$X, map_data$Y))
dmvnorm(x = ?, mean = c(x_mean, y_mean), sigma = covar)
Run Code Online (Sandbox Code Playgroud)
x参数的用途是什么?为什么需要这个?
我在数据库中遇到过这样的查询:
SELECT col_a
FROM my_table
WHERE
nvl(col_b, 0) in
nvl(nvl(:arg, col_b), 0)
Run Code Online (Sandbox Code Playgroud)
这将从我的表返回col_a,其中:
这似乎是一种非常复杂的方式来返回与输入参数匹配的一个或所有记录,或者只是根据输入参数的值选择整个表.
有没有更简单的方法来达到同样的效果?
另外,我注意到NVLOracle是特定的,在这个实例中使用它有什么好处COALESCE吗?
捕获异常时,标准指导是按值抛出,通过引用捕获.据我了解,这有两个原因:
如果我们有一个我们没有在catch块中定义异常名称的场景,那么这些问题(实际上是1.,因为如果我们没有变量的名称,切片不会成为问题)仍然有效吗?
例如:
catch(my_exception)
{ ... }
Run Code Online (Sandbox Code Playgroud)
要么
catch(my_exception &)
{ ... }
Run Code Online (Sandbox Code Playgroud)
如果在这种情况下由值捕获的异常,是否仍有可能终止程序?我的感觉是技术上仍然可行.
注意:我问这个是因为我必须审查某人的代码,在这种情况下按值放置.如问题中所示,我不完全确定任何一种选择的技术影响,但我认为就整体而言,最好在这种情况下通过引用而不管(在任何情况下都没有通过引用捕获的缺点) .