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.