Reputation: 299
I have a function called FunctionCombiner (of base type ValuationFunction) which contains other valuationFunctions like so:
class FunctionCombiner : public valuationFunction
{
public:
FunctionCombiner(std::vector<std::shared_ptr<valuationFunction>>& Inner_);
void ValueInstrument();
std::vector<std::string> GetuniqueIdentifier() const;
void RiskFactorAdd(double increment, RiskFactor simulatedRiskFactor);
void RiskFactorMultiply(double factor, RiskFactor simulatedRiskFactor);
virtual valuationFunction* clone() const;
private:
std::vector<std::shared_ptr<valuationFunction>> Inner;
};
What I need to do is create a function that returns references to these "inner" functions but I'm unsure how to go about it, everything I've tried seems to fail syntactically. If I was returning just a refence (not inside a vector) I would go about it like this:
valuationFunction& FunctionCombiner ::GetInner()
{
return *this;
}
I've tried returning something like std::vector< valuationFunction&>
but the compiler doesn't seem to like that very much. What is the correct way to go about this?
The end goal is to collect all these references to the inner functions (from several FunctionCombiners or different valuationFunctions) in order to compare them and sort out duplicates later on.
EDIT: From the answer I've now implemented the function that returns the inner reference like follows: My functions look like this now for the "inner" classes:
std::vector<std::reference_wrapper<valuationFunction>> StockPriceFunction::GetInnerReference()
{
std::vector<std::reference_wrapper<valuationFunction>> innerVector(1);
innerVector.push_back(std::ref(*this));
return innerVector;
}
And like this for the combiner:
std::vector<std::reference_wrapper<valuationFunction>> FunctionCombiner::GetInnerReference()
{
std::vector<std::reference_wrapper<valuationFunction>> innerVector(Inner.size());
for (unsigned long i = 0; i < Inner.size(); ++i) {
std::vector<std::reference_wrapper<valuationFunction>> innerInnerVector = Inner[i]->GetInnerReference();
innerVector.insert(innerVector.end(), innerInnerVector.begin(), innerInnerVector.end());
}
return innerVector;
}
But it's not compiling and giving me strange errors, what am I doing wrong here?
Upvotes: 0
Views: 94
Reputation: 5503
In order to store references in a std::vector
you'll have to use an std::reference_wrapper.
#include <functional>
#include <vector>
int main( )
{
std::vector<int> ints{ 1, 2, 3, 4, 5 };
std::vector<std::reference_wrapper<int>> references;
for( auto& i : ints )
references.push_back( i );
auto& ref{ references[ 1 ].get( ) };
ref += 20;
// Prints 22.
std::cout << ints[ 1 ] << '\n';
}
Here is another example which more closely resembles what you're trying to do (I also included what headers you need).
#include <iostream>
#include <functional>
#include <vector>
#include <memory>
struct ValuationFunction
{
ValuationFunction( int prop )
: property{ prop } { }
int property;
};
// Converts the vector of pointers to a vector
// of references.
static std::vector<std::reference_wrapper<ValuationFunction>>
ToReference( const std::vector<std::shared_ptr<ValuationFunction>>& pointers )
{
std::vector<std::reference_wrapper<ValuationFunction>> references;
references.reserve( pointers.size( ) );
for ( auto& pointer : pointers )
references.emplace_back( *pointer );
return references;
}
int main( )
{
std::vector<std::shared_ptr<ValuationFunction>> pointers
{
std::make_shared<ValuationFunction>( 1 ),
std::make_shared<ValuationFunction>( 2 ),
std::make_shared<ValuationFunction>( 3 ),
std::make_shared<ValuationFunction>( 4 )
};
auto references{ ToReference( pointers ) };
// Use 'std::reference_wrapper.get( )' to get
// access to the contained reference.
for ( auto& ref : references )
std::cout << "Before: " << ref.get( ).property << '\n';
// Change the property value of each 'ValuationFunction'
// in the original list.
for ( auto& pointer : pointers )
pointer->property += 10;
// Re-print the property value of each reference and see
// how they have all increased by 10.
for ( auto& ref : references )
std::cout << "After: " << ref.get( ).property << '\n';
}
Upvotes: 1