Компилятор не распознает перегруженный метод - PullRequest
1 голос
/ 14 октября 2019

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

I 'Мы испробовали все способы доступа к методу и итераторам, но не повезло.

Мой код находится здесь: https://godbolt.org/z/-esVdc и воспроизведен здесь для вашего удобства.

#include <vector>
#include <map>
#include <ctime>

template<typename Value>
class AccessorDetail final
{

public:
    using Container = std::deque<Value>;
    using ContainerIter = typename std::deque<Value>::iterator;

    struct Candle final
    {
        Container open;
        Container high;
        Container low;
        Container close;
    };

    using Timeframe = int;
    using CandleContainer = std::vector<Candle>;


    AccessorDetail(const int timeframe) {};
    ~AccessorDetail() {};

    constexpr auto data() noexcept -> auto&
    {
        return data_;
    }

    constexpr auto data() const noexcept -> const auto&
    {
        return data_;
    }

    auto erase(const int applied_price, const int timeframe, const ContainerIter start, const ContainerIter finish) -> int
    {
        switch (applied_price)
        {
        PRICE_OPEN: data_.at(timeframe).get().open.erase(start, finish); break;
        PRICE_HIGH: data_.at(timeframe).get().high.erase(start, finish); break;
        PRICE_LOW: data_.at(timeframe).get().low.erase(start, finish); break;
        PRICE_CLOSE: data_.at(timeframe).get().close.erase(start, finish); break;
        }

        return 0;
    }

private:
    std::map<Timeframe, std::reference_wrapper<Candle>> data_;
    CandleContainer candles_;
};

template<typename T, typename U>
struct TimeSeriesData final
{
    static_assert(std::is_floating_point<T>::value, "");
    static_assert(std::is_integral<U>::value, "");

    T price_0;
    U time;
};

class DataAccessor 
{
public:

    DataAccessor(const int timeframe): detail_(timeframe) {};
    ~DataAccessor() {};

    constexpr auto detail() noexcept -> auto&
    {
        return detail_;
    }

    constexpr auto detail() const noexcept -> const auto&
    {
        return detail_;
    }

private:
    AccessorDetail<TimeSeriesData<double, std::time_t>> detail_;
};

auto main() -> int
{
    DataAccessor data_{1};

    auto start = data_.detail().data().begin();
    auto finish = data_.detail().data().end();
    data_.detail().erase(0, 1, start, finish);
}

Этодолжен скомпилироваться, но вместо этого я вижу следующую ошибку в Visual Studio:

Error   C2664   'int AccessorDetail<TimeSeriesData<double,time_t>>::erase(const int,const int,const std::_Deque_iterator<std::_Deque_val<std::_Deque_simple_types<_Ty>>>,const std::_Deque_iterator<std::_Deque_val<std::_Deque_simple_types<_Ty>>>)': cannot convert argument 3 from 'std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<_Ty>>>' to 'const std::_Deque_iterator<std::_Deque_val<std::_Deque_simple_types<_Ty>>>'   

в этой строке: data_.detail().erase(0, 1, start, finish);

Что я делаю не так, пожалуйста?

Ответы [ 2 ]

1 голос
/ 14 октября 2019

Ваши итераторы start и finish имеют тип std::map<Timeframe, std::reference_wrapper<Candle>>::iterator. Тем не менее, метод erase ожидает итераторы типа std::deque<Value>::iterator. Эти типы несовместимы, поэтому компилятор вправе отказаться от компиляции.

Использование вами auto скрывает типы от читателя кода. Это недостаток auto.

0 голосов
/ 14 октября 2019

Было несколько ошибок ... ни в одном случае не было переключателя в методе стирания, и он неправильно указывал правильный уровень иерархии, чтобы инициализировать начальный и конечный итераторы. Код здесь: https://godbolt.org/z/aWhFTc и здесь:

#include <deque>
#include <vector>
#include <map>
#include <ctime>

template<typename Value>
class AccessorDetail final
{

public:
    using Container = std::deque<Value>;
    using ContainerIter = typename std::deque<Value>::iterator;

    struct Candle final
    {
        Container open;
        Container high;
        Container low;
        Container close;
    };

    using Timeframe = int;
    using CandleContainer = std::vector<Candle>;


    AccessorDetail(const int timeframe) {};
    ~AccessorDetail() {};

    constexpr auto data() noexcept -> auto&
    {
        return data_;
    }

    constexpr auto data() const noexcept -> const auto&
    {
        return data_;
    }

    auto erase(const int applied_price, const int timeframe, const ContainerIter start, const ContainerIter finish) -> int
    {
        switch (applied_price)
        {
        case 0: data_.at(timeframe).get().open.erase(start, finish); break;
        case 1: data_.at(timeframe).get().high.erase(start, finish); break;
        case 2: data_.at(timeframe).get().low.erase(start, finish); break;
        case 3: data_.at(timeframe).get().close.erase(start, finish); break;
        }

        return 0;
    }

private:
    std::map<Timeframe, std::reference_wrapper<Candle>> data_;
    CandleContainer candles_;
};

template<typename T, typename U>
struct TimeSeriesData final
{
    static_assert(std::is_floating_point<T>::value, "");
    static_assert(std::is_integral<U>::value, "");

    T price_0;
    U time;
};

class DataAccessor 
{
public:

    DataAccessor(const int timeframe): detail_(timeframe) {};
    ~DataAccessor() {};

    constexpr auto detail() noexcept -> auto&
    {
        return detail_;
    }

    constexpr auto detail() const noexcept -> const auto&
    {
        return detail_;
    }

private:
    AccessorDetail<TimeSeriesData<double, std::time_t>> detail_;
};

auto main() -> int
{
    DataAccessor data_{1};
    auto timeframe = int{1};

    auto start = data_.detail().data().at(timeframe).get().open.begin();
    auto finish = data_.detail().data().at(timeframe).get().open.end();
    data_.detail().erase(0, 1, start, finish);
}
...