Reputation: 526
I have a class like the following:
template<typename ... TTypes>
class Composite {
public:
//Composite() : null(true) { }
Composite(TTypes... values) : values(std::make_tuple(values...)), null(false) { }
private:
bool null;
std::tuple<TTypes...> values;
};
int main(int argc, char *argv[]) {
Composite<int, char, int> a1;
}
But this leads to an error because the second constructor would override the first one with TTypes = {}. Is there any way to keep the empty constructor?
Best, Moritz
Upvotes: 4
Views: 1540
Reputation: 2033
Since none of the existing answers so actually solve the problem, but there is a solution by Piotr Skotnicki hidden in the comments, I'm just gonna repost it here for visibility:
#include <tuple>
#include <type_traits>
template<typename ... TTypes>
class Composite {
public:
Composite() : null(true) { }
template <std::size_t N = sizeof...(TTypes), typename std::enable_if<(N>0), int>::type = 0>
Composite(TTypes... values) : values(std::make_tuple(values...)), null(false) { }
private:
bool null;
std::tuple<TTypes...> values;
};
int main(int argc, char *argv[]) {
Composite<int, char, int> a1;
Composite<> a2;
}
Upvotes: 4
Reputation: 3096
The case where your parameter pack TTypes
is empty makes the default constructor ambiguous. If you plan to provide at least 1 parameter, then you can specify an additional parameter:
template<typename TType, typename ... TTypes>
class Composite {
public:
Composite() : null(true) { }
Composite(TType first, TTypes... rest) :
values(std::make_tuple(first,rest...)),
null(false)
{
}
private:
bool null;
std::tuple<TType,TTypes...> values;
};
int main(int argc, char *argv[]) {
Composite<int, char, int> a1;
}
However, take into account that this functionality is provided by std::optional
, so it should be better using it.
template < typename... TTypes >
using Composite = std::optional<std::tuple<TTypes...>>;
Upvotes: 0
Reputation: 206577
I am not sure whether the following work around is an option for you:
template<typename ... TTypes>
class Composite : public ValueSet {
public:
Composite(TTypes... values) { }
};
template<>
class Composite<> : public ValueSet {
public:
Composite() : ValueSet() { }
};
but it works.
Upvotes: 0