Возврат вектора ссылок из класса - PullRequest
0 голосов
/ 30 мая 2020

У меня есть функция под названием FunctionCombiner (базового типа ValuationFunction), которая содержит другие функции оценки, например:

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;
};

Мне нужно создать функцию, которая возвращает ссылки на эти «внутренние» функции, но Я не уверен, как go об этом, все, что я пробовал, похоже, синтаксически не работает. Если бы я возвращал только ссылку (не внутри вектора), я бы go об этом сказал бы так:

valuationFunction& FunctionCombiner ::GetInner()
{
    return *this;
}

Я пытался вернуть что-то вроде std::vector< valuationFunction&>, но компилятор, похоже, не очень нравится. Как правильно сообщить об этом go?

Конечная цель - собрать все эти ссылки на внутренние функции (из нескольких FunctionCombiners или различных функций оценки), чтобы сравнить их и отсортировать дубликаты позже.

EDIT: Из ответа Я реализовал функцию, которая возвращает внутреннюю ссылку, как показано ниже: Мои функции теперь выглядят так для «внутренних» классов:

std::vector<std::reference_wrapper<valuationFunction>> StockPriceFunction::GetInnerReference()
    {
        std::vector<std::reference_wrapper<valuationFunction>> innerVector(1);
        innerVector.push_back(std::ref(*this));
        return innerVector;
    }

И вот так для комбайнера:

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;
}

Но он не компилируется и не выдает странные ошибки, что я здесь делаю не так?

1 Ответ

1 голос
/ 30 мая 2020

Чтобы хранить ссылки в std::vector, вам нужно будет использовать 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';
}

Вот еще один пример, который более похож на то, что вы пытаемся сделать (я также включил, какие заголовки вам нужны).

#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';    
}
...