Reputation: 3063
I have a code that uses type deduction like this:
template <typename... Ttypes>
Tuple<Ttypes...> makeTuple(Ttypes... args) {
Tuple<Ttypes...> result;
fillTuple<0>(result, args...);
return result;
}
I want to encapsulate the result to a class which is not a class template. The only way, and this is reasonable, is to have it as a static const
member like this:
struct A {
static const auto t = makeTuple(1,2,3,'c');
};
and I get: error: in-class initializer for static data member of type 'const Tuple<int, int, int, char>' requires 'constexpr' specifier static const auto tuple = makeTuple(1,2,3,'c');
.
If I use
struct A {
static const auto constexpr t = makeTuple(1,2,3,'c');
};
I get error: constexpr variable 'tuple' must be initialized by a constant expression
.
Moreover, using constexpr
is not good for me, because I' like to use non-literal types in a tuple.
Compiler Clang with -std=c++14.
Is there a way to get what I want?
Upvotes: 0
Views: 764
Reputation: 71
You should be able to accomplish this without declaring the member static. auto is useful for type deduction when it is also being initialized. If declaration is needed prior to initialization you can use decltype instead.
GeeksForGeeks has a good introduction to decltype. https://www.geeksforgeeks.org/type-inference-in-c-auto-and-decltype/
#include <iostream>
#include <tuple>
#include <memory>
using namespace std;
template<typename... Types>
tuple<Types...> makeTuple(Types... types)
{
return tuple<Types...>();
}
//I'm using these two functions just to show
//that non constexpr functions can be used to determine type
int generateInt()
{
return 1;
}
char generateChar()
{
return 'a';
}
struct A
{
decltype(makeTuple(generateInt(), generateChar())) t;
A() : t(makeTuple(1, 'a'))
{
}
};
int main()
{
A a;
return 0;
}
Upvotes: 1
Reputation: 52461
Something along these lines, perhaps:
struct A {
using TupleType = decltype(makeTuple(1,2,3,'c'));
static const TupleType t;
};
// In a .cpp file
const A::TupleType A::t = makeTuple(1,2,3,'c');
Somewhat more elaborate, but avoids some repetition:
struct A {
static auto MakeMyTuple() { return makeTuple(1,2,3,'c'); }
using TupleType = decltype(MakeMyTuple());
static const TupleType t;
};
// In a .cpp file
const A::TupleType A::t = A::MakeMyTuple();
This way, arguments to makeTuple
are all in one place.
Upvotes: 2