Reputation: 17375
Comming from Java I would like to implement the following "test multiple implementations" idiom in C++
void testMethod() {
List veryBigList = createNewRandomList(10000);
Algo algo = createAlgo(veryBigList);
algo.run();
}
// this can be overwritten from a subclass to test against different algo
Algo createAlgo(List list) {
Algo a(list);
return a;
}
List createNewRandomList(int size) {
List l = new ArrayList(size);
// fill list with random objects
return l;
}
I'm a bit lost how to do this the right way in C++ ... when I'm doing it this way:
void test_method() {
vector<string> big_list(10000);
init_random_list(big_list);
algo my_algo = create_algo(big_list);
my_algo.run();
}
algo create_algo(vector<string> list) {
algo a(list);
return a;
}
void init_random_list(vector<string> list) {
// fill list with random objects
}
then what will C++ do? Will it copy the full list to go to create_algo and then on return it'll copy the algo (and the list again)??
But when using call by reference I would access the reference in test_method outside of the scope of algo causing a lot trouble and violating the RAII principle, right?
I know for some implementations of C++ they optimize speed for call by value according to this doc, but can I rely on that for g++ and visual c++?
Upvotes: 2
Views: 298
Reputation: 137870
The semantics of algo
appear to be a bit unusual. It looks like a functor class, and you are passing and storing one argument at construction time. Most often, C++ functor classes are stateless.
I think it would be more canonical to do
std::function< algo_result( algo_args ) > // return generic functor type
create_algo(std::vector<std::string> &list) {
return std::bind( algo(), std::ref( list ) ); // store reference
// result of std::bind implicitly converts to std::function
}
std::bind
returns a stateful functor object, and it works together with std::ref
to allow you to keep a reference inside that object without manually defining how the reference is stored. Now the algo
object and the reference are copied inside the std::function
, but that should be cheap.
On the other hand, if algo
is truly stateful and requires a list
to exist, it should be an argument to the constructor and you should not use a factory function.
Upvotes: 0
Reputation: 208406
Assuming that the code is exactly as you posted, and that algo
can be modified to store a reference, then you probably want to pass and store a reference.
Upvotes: 2
Reputation: 46589
First of all, why not just call algo my_algo(biglist)
in test_method
, bypassing the call to create_algo
?
But yes, you're right, this will create copies (in principle, although in practice it may not, if you're lucky). So the real question is, what do you do in the algo with the list? E.G. if you treat the list as read-only, using references is fine.
If not, simply changing the call to create_algo to use a reference will prevent one (potential) copy.
Upvotes: 0