mardi 27 mars 2018

Making a tuple of PoD from a tuple of Strong Types

I have a StrongType<> class that enforces strong typing on PoDs:

template <typename T, typename TAG>
class StrongType {
private:
    std::string mName;
    T mValue;
public:
    explicit StrongType(std::string n) : mName(n), mValue() {}
    explicit StrongType(std::string n, T v)
        : mName(n), mValue(std::move(v)) {
    }

    const T &value() const { return mValue; }
    std::string name() const { return mName; }
}; 

And I have a class that keeps a tuple of StrongTypes and needs to return a non-strong-typed tuple (indeed it should call a function with non-strong-typed arguments):

struct aTag {};
struct bTag {};
struct cTag {};

using aType = utils::StrongType<int, aTag>;
using bType = utils::StrongType<std::string, bTag>;
using cType = utils::StrongType<int, cTag>;

int main()
{
    aType a("a", 2);
    bType b("b", std::string {"b"});
    cType c("c", 10);

    AdvTuple<aType,bType,cType> t(a,b,c);

    //auto nt = t.getTuple();
    //std::cout << std::tuple_size<decltype(nt)>() << "\n";
    //std::cout << std::get<0>(nt) << "\n";

    //nt.call([](aType ra, bType rb, cType rc) {
    //});

    return 0;
}

This is the implementation I made, but it doesn't compile:

#include <tuple>

template <typename ...T>
class AdvTuple {
private:
    std::tuple<T...> aTuple;
public:
    explicit AdvTuple(T... ts)
        : aTuple(std::make_tuple(ts...)) {
    }

    template <int i>
    decltype(std::get<i>(aTuple).value()) get() const {
        return std::get<i>(aTuple).value();
    }

    template <int N = 0, typename ...TA, std::enable_if<N < sizeof...(TA)> >
    auto getImpl(std::tuple<TA...> t) {
        return std::tuple_cat(std::make_tuple(std::get<N>(t)), getImpl<N+1>(t));
    };

    template <typename ...Q>
    std::tuple<Q...> getTuple() const {
        return getImpl<0>(aTuple);
    }
};

This is the message from the compiler (clang on mac):

In file included from /Users/happycactus/Documents/Progetti/Experiments/tupletraits/main.cpp:3: /Users/happycactus/Documents/Progetti/Experiments/tupletraits/tupletypes.h:32:16: error: no matching member function for call to 'getImpl' return getImpl<0>(aTuple); ^~~~~~~~~~

/Users/happycactus/Documents/Progetti/Experiments/tupletraits/main.cpp:25:17: note: in instantiation of function template specialization 'AdvTuple, utils::StrongType, bTag>, utils::StrongType >::getTuple<>' requested here auto nt = t.getTuple(); ^

/Users/happycactus/Documents/Progetti/Experiments/tupletraits/tupletypes.h:26:10: note: candidate template ignored: couldn't infer template argument '' auto getImpl(std::tuple t) { ^ 1 error generated.

1) How can fix it?

2) How can I implement the call() function with the lambda / function<> with deduced PoD types? Even non StrongTyped is ok.

I can use C++11 and 14.

Thanks

Aucun commentaire:

Enregistrer un commentaire