0

I am learning the new c++11 features (was doing Java for a few years, trying to get back), and came across tuples. So I implemented something that compiles and works in VS2013 but not under gcc (yes I do pass in the c++11 switch, also tried http://ideone.com/ c++14 gcc 4.9.2, get the same error).

The idea would be that I have some data record class that has a function GetNumber() and another function GetText(). I'd like to implement a template class with the template argument of a tuple. This template class would fill the tuple elements by type, for a wstring it would call GetText() on my data record class, for an int it would call GetNumber(). Then it would save the tuple into a vector and would return it.

Here is the code that works in VS2013 and not under gcc:

#include <functional>
#include <iostream>
#include <tuple>        // std::tuple, std::get, std::tie, std::ignore
#include <vector>
#include <algorithm>
#include <string>
#include <memory>
#include <exception>

class MyValues { 
public:
    int GetNum() const { return 999; }
    std::wstring GetText() const { return L"blah"; } 
};

template <class TVal> class GetVal 
{ 
public:
    TVal Get(const MyValues& v)
    {
        // This static assert with this code breaks the build in gcc
        static_assert(0, "Unsupported datatype");
    }
}; 
template <> 
class GetVal <int> 
{
public:
    int Get(const MyValues& v) { return v.GetNum(); }
 };
template <>
class GetVal <std::wstring> 
{
public:
    std::wstring Get(const MyValues& v) { return v.GetText(); }
};

template <class TTuple> 
class TupleMaker 
{
    MyValues mv_; public:
    std::vector<TTuple> loadData()
    {
        std::vector<TTuple> ret;
        TTuple tpl = std::make_tuple(
            GetVal<std::tuple_element<0, TTuple>::type>().Get(mv_),
            GetVal<std::tuple_element<1, TTuple>::type>().Get(mv_));
            // The code below does work in GCC, but how to use the
            // template argument as shown above?
            //GetVal<std::tuple_element<0, std::tuple<int, std::wstring>>::type>().Get(mv_),
            //GetVal<std::tuple_element<1, std::tuple<int, std::wstring>>::type>().Get(mv_));
        ret.push_back(tpl);
        return ret;
    } };


int main(int argc, char* argv[]) 
{
    std::vector<std::tuple<int, std::wstring>> data =
        TupleMaker<std::tuple<int, std::wstring>>().loadData();

    std::wcout << std::get<0>(data[0]) << std::endl;
    std::wcout << std::get<1>(data[0]) << std::endl;

    return 0; 
}

Wherever gcc complains I put comments to the above code. Essentially I cannot use the template argument TTuple in TupleMaker's LoadData and the static_assert breaks the build even though specializations of the GetVal class cover all the cases that I want to use GetVal for.

Any help would be appreciated, thank you for reading this.

bjdodo
  • 331
  • 3
  • 11

0 Answers0