Dedukcja typu na podstawie std::decay_t<>::value_type

0

Głównie chodzi o dedukcje typu, abym mógł wypełniać klasą Filler prywatne pole klasy Foo
Wg wszelkich źródeł czytanych kod powinien się kompilować, a nie kompiluje (na ideone jest OK).
Już dwa razy przeinstalowałem VS i nadal nic (od wczoraj łapie zwiechy).
Zerknijcie, jak możecie czy to jest OK (czy to nie jakiś bug - szukam dalej).

#include <iostream>
#include <string>
#include <map>
#include <type_traits>
using namespace std;

using MapSS = map<string, string>;

class Printer {
public:
    template <class C>
    void print(const C& coll) {
        for (auto const& el : coll)
            cout << el.first << " " << el.second << '\n';
        cout << '\n';
    }
};

class Filler {
public:
    template <class C>
    void fill(C& coll) {
        string key, value;
        cin >> key >> value;
        using deducedType = typename decay_t<C>::value_type;
        deducedType deducedValue = { key, value };
        coll.insert(std::forward<deducedType>(deducedValue));
    }
};

class Foo{
    MapSS coll;
public:
    Foo() = default;

    void appendToMap() {
        for (int i = 0; i < 3; ++i) {
            Filler filler;
            filler.fill(coll);
        }
    }

    void showMap() const {
        Printer printer;
        printer.print(coll);
    }
};

int main()
{
    Foo f;
    f.appendToMap();
    f.showMap();
} 
Error	C2065	'deducedValue': undeclared identifier
Error	C2146	syntax error: missing ';' before identifier 'deducedValue' 
2

std::decay_t nie ma żadnego ::value_type. Powinno być using deducedType = std::decay_t<C>;. std::decay_t zostało dodane w C++14, nie wiem, czy VS to obsługuje. Alternatywa to using deducedType = typename std::decay<C>::type;

Edit: No dobra, skoro spodziewasz się kontenera to spoko. Patrz niżej.

Poza tym nie wgłębiałem się w kod. Dziwnie wygląda ten std::forward tam.

4

Brzmi jak problem VS z two phased lookup i deducedType nie jest traktowane jako typ zależny. Jedyne co mogę poradzić to szukaj workaroundów reorganizując kod lub użyj prawdziwego kompilatora C++ :) (co nie znaczy, że ktoś inny nie będzie w stanie nic poradzić!).

Tak przy okazji:

        deducedType deducedValue = { key, value };
        coll.insert(std::forward<deducedType>(deducedValue));

Ten kawałek nie ma zbytnio sensu:

  1. Mało które value_type można inicjalizować dwoma parametrami, a w przypadkach gdzie można jest to pair<const T, U>, więc generyczność tego rozwiązania jest niewielka ;)
  2. std::forward nie ma tu zbytnio zastosowania, jeśli już to std::move (ale i tak skopiujesz key)
0

Jutro powalczę: coś z visualem.
Ten nie działa:

template <class C>
    void fill(C& coll) {
        string key, value;
        cin >> key >> value;        
        coll.insert(make_pair(key, value));
    } 

ale ten zaskoczył (dziwna sprawa):

template <class C>
    void fill(C& coll) {
        string key, value;
        cin >> key >> value;
        using deducedType = typename decay_t<C>::value_type; // samo type lub bez niczego daje więcej błędów
        deducedType deducedValue = make_pair(key, value);
        coll.insert(deducedValue);
    } 

Przynajmniej nie błądzę po omacku.
Dzięki za zainteresowanie.

0

Był jakiś błąd aktualizacji. Przeinstalowałem i aktualizację dałem offline. Wszystko gra.
Dzięki @Endrju @kq za skazówki.
@satirev za sprawdzenie u siebie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1