在C++中,每当函数创建许多(数百或数千)个值时,我曾经让调用者传递一个数组,然后我的函数用输出值填充:
void computeValues(int input, std::vector<int>& output);
Run Code Online (Sandbox Code Playgroud)
因此,该函数将output使用它计算的值填充向量.但这并不是真正优秀的C++风格,正如我现在意识到的那样.
以下函数签名更好,因为它不承诺使用a std::vector,但可以使用任何容器:
void computeValues(int input, std::insert_iterator<int> outputInserter);
Run Code Online (Sandbox Code Playgroud)
现在,来电者可以与一些人打电话inserter:
std::vector<int> values; // or could use deque, list, map, ...
computeValues(input, std::back_inserter(values));
Run Code Online (Sandbox Code Playgroud)
同样,我们不承诺std::vector专门使用,这很好,因为用户可能只需要std::set等等的值(我应该传递iteratorby值还是引用?)
我的问题是:这是insert_iterator正确的还是标准的方式吗?还是有更好的东西?
编辑:我编辑了这个问题,以明确我不是在谈论返回两个或三个值,而是数百或数千.(想象一下,您已经返回在某个目录中找到的所有文件,或图表中的所有边缘等)
传递函数对象的以下小程序有什么问题?
#include <iostream>
#include <functional>
void foo(const std::unary_function<const std::string&, void>& fct) {
const std::string str = "test";
fct(str); // error
}
class MyFct : public std::unary_function<const std::string&, void> {
public:
void operator()(const std::string& str) const {
std::cout << str << std::endl;
}
};
int main(int argc, char** argv){
MyFct f;
foo(f);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在第6行收到以下错误:
no match for call to
`(const std::unary_function<const std::string&, void>) (const std::string&)'
Run Code Online (Sandbox Code Playgroud) 我使用以下代码将以下代码编译为共享库g++ -shared ...:
class Foo {
public:
Foo() {}
virtual ~Foo() = 0;
virtual int Bar() = 0;
};
class TestFoo : public Foo {
public:
int Bar() { return 0; }
};
extern "C" {
Foo* foo;
void init() {
// Runtime error: undefined symbol: _ZN3FooD2Ev
foo = new TestFoo(); // causes error
}
void cleanup() { delete(foo); }
void bar() { foo->Bar(); }
}
Run Code Online (Sandbox Code Playgroud)
关键是要作为一个简单的暴露我的课(这里只是很小的玩具类为例)的功能C与三个功能API init,cleanup和bar.
当我尝试加载共享库(使用dyn.loadin …
c++ compilation shared-libraries linker-errors undefined-symbol
在Perl中,数组索引-1表示最后一个元素:
@F=(1,2,3);
print $F[-1]; # result: 3
Run Code Online (Sandbox Code Playgroud)
您也可以使用$#符号,这里$#F:
@F=(1,2,3);
print $F[$#F]; # result: 3
Run Code Online (Sandbox Code Playgroud)
那么-1,$#F当我想指定范围中的最后一个元素时,为什么不给出相同的结果:
print @F[1..$#F]; # 23
print @F[1..-1]; # <empty>
Run Code Online (Sandbox Code Playgroud)
数组@F[1..-1]应该包含从元素1到最后一个元素的所有元素,不是吗?
以下代码给出了一条错误消息:
#!/usr/bin/perl -w
foreach my $var (0, 1, 2){
$var += 2;
print "$var\n";
}
Run Code Online (Sandbox Code Playgroud)
Modification of a read-only value attempted at test.pl line 4.
有没有办法修改$var?(我只是好奇地问;看到这个错误信息我真的很惊讶.)
以下代码在输出时只出现错误std::endl:
#include <iostream>
#include <sstream>
struct MyStream {
std::ostream* out_;
MyStream(std::ostream* out) : out_(out) {}
std::ostream& operator<<(const std::string& s) {
(*out_) << s;
return *out_;
}
};
template<class OutputStream>
struct Foo {
OutputStream* out_;
Foo(OutputStream* out) : out_(out) {}
void test() {
(*out_) << "OK" << std::endl;
(*out_) << std::endl; // ERROR
}
};
int main(int argc, char** argv){
MyStream out(&std::cout);
Foo<MyStream> foo(&out);
foo.test();
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
错误是:
stream1.cpp:19: error: no match for 'operator<<' in '*((Foo<MyStream>*)this)->Foo<MyStream>::out_ << std::endl' …Run Code Online (Sandbox Code Playgroud) 我经常有一些类,它们大多只是一些STL容器的包装器,如下所示:
class Foo {
public:
typedef std::vector<whatever> Vec;
typedef Vec::size_type size_type;
const Vec& GetVec() { return vec_; }
size_type size() { return vec_.size() }
private:
Vec vec_;
};
Run Code Online (Sandbox Code Playgroud)
我不太肯定回来size_type.通常,某些函数会调用size()并将该值传递给另一个函数,并且该函数将使用它并可能将其传递给它.现在每个人都必须包含那个Foo标题,虽然我真的只是传递一些大小值,但这应该只是unsigned int...?这里做什么是正确的?最好的做法是size_type到处使用吗?
以下代码无法编译:
#include <iostream>
class Foo {
std::string s;
public:
const std::string& GetString() const { return s; }
std::string* GetString() { return &s; }
};
int main(int argc, char** argv){
Foo foo;
const std::string& s = foo.GetString(); // error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
const1.cc:11: error:
invalid initialization of reference of type 'const std::string&'
from expression of type 'std::string*
Run Code Online (Sandbox Code Playgroud)
它确实有一定意义,因为foo它不是类型const Foo,只是Foo,因此编译器想要使用非const函数.但是,为什么不能通过GetString查看我赋给它的(类型)变量来识别我想调用const 函数?我发现这种情况令人惊讶.
在C++中,如何删除包含所有包含文件的目录?我知道有rmdir,但它只会删除非空目录,所以我如何首先列出并删除所有包含的文件?
我知道使用Boost Filesystem应该不会很难,但我有点想避免构建并依赖它来完成这个小任务......
迭代时std::map<X,std::vector<Y> >,我可以对向量进行排序,还是可能使迭代器无效?
换句话说,以下代码是否可以?
typedef std::map<int, std::vector<int> > Map;
Map m;
for (Map::iterator it = m.begin(); it != m.end(); ++it) {
std::sort(it->second.begin(), it->second.end());
}
Run Code Online (Sandbox Code Playgroud)