我正在使用与Boost 1.60(无C ++ 11)兼容的VS2008代码。我有一个第三方库,它返回一个类似列表的界面。我想获取列表的元素并将它们放在std :: vector中。 track_list
类有一个next
方法,它返回一个指向轨道指针track**
的指针。
我在想我可以使用std :: generate来填充与track_list
相同大小的向量。我能够提出boost::bind(&track_list::next, tracks)
来获取track**
,但我不确定如何添加解除引用部分以使track*
进入vector<track*>
。
此外,实际上我知道从specific_track*
投出的track*
是安全的。所以我真正想要的是(specific_track*)(*boost::bind(&track_list::next, tracks))
的内容,但我不确定如何在语法上构造它。我是在正确的轨道上吗?我看了一下boost lambdas,但是生成器函数没有参数。
编辑:也许更简单的例子可能有助于澄清我正在尝试做的事情。
int** get_ptr_num() { int* i = new int(5); return new int*(i); }
int* get_num() { return new int(5); }
int main() {
std::vector<int*> nums(10);
std::generate(nums.begin(), nums.end(), get_num) // compiles
std::generate(nums.begin(), nums.end(), get_ptr_num) // cannot convert from int** to int*
}
基本上我只想将get_ptr_num包装在某种bind或lambda中来进行解引用而不创建单独的函数来执行此操作。
第二部分,演员,会是这样的:
int main() {
std::vector<double*> nums(10);
std::generate(nums.begin(), nums.end(), get_ptr_num) // cannot convert from int** to double*
}
这似乎对C ++ 11 lambdas来说是微不足道的,但我不能使用C ++ 11。
关于这个成员函数的最后一部分将更像是这样:
class IntGenerator {
public:
int** get_ptr_num() { int* i = new int(5); return new int*(i); }
}
int main() {
IntGenerator int_gen;
std::vector<int*> nums(10);
std::generate(nums.begin(), nums.end(), boost::bind(&IntGenerator::get_ptr_num, int_gen)) // cannot convert from int** to int*
}
答案 0 :(得分:0)
您可以使用函数输入迭代器:
<强> Live On Coliru 强>
#include <boost/iterator/function_input_iterator.hpp>
#include <vector>
#include <functional>
#include <iostream>
#include <array>
namespace TheAPI {
struct track_list {
std::array<char const*, 6> titles {{ "one", "two", "three", "four", "five", "six" }};
size_t length() const { return titles.size(); }
struct Iterator {
char const* const* raw;
char const* next() { return *raw++; }
};
Iterator get_iterator() const { return {titles.begin()}; };
};
}
int main() {
TheAPI::track_list tl;
auto iter = tl.get_iterator();
auto gen = std::bind(&TheAPI::track_list::Iterator::next, std::ref(iter));
auto first = boost::make_function_input_iterator(gen, 0),
last = boost::make_function_input_iterator(gen, 6);
std::vector<std::string> titles(first, last);
std::copy(titles.begin(), titles.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
}
当然,如果您考虑generate
,generate_n
可能会更简单:
<强> Live On Coliru 强>
#include <functional>
#include <iterator>
#include <algorithm>
#include <iostream>
#include <array>
namespace TheAPI {
struct track_list {
std::array<char const*, 6> titles {{ "one", "two", "three", "four", "five", "six" }};
size_t length() const { return titles.size(); }
struct Iterator {
char const* const* raw;
char const* next() { return *raw++; }
};
Iterator get_iterator() const { return {titles.begin()}; };
};
}
int main() {
TheAPI::track_list tl;
auto iter = tl.get_iterator();
auto gen = std::bind(&TheAPI::track_list::Iterator::next, std::ref(iter));
std::generate_n(std::ostream_iterator<std::string>{std::cout, "\n"}, tl.length(), gen);
}
使用
填充矢量std::vector<std::string> my_vector;
std::generate_n(back_inserter(my_vector), tl.length(), gen);
两个程序都打印
one
two
three
four
five
six