I have following code:
class TR_AgentInfo : public tuple<
long long, //AgentId
string, //AgentIp
>
{
public:
TR_AgentInfo() {}
TR_AgentInfo(
const long long& AgentId,
const string& AgentIp,
)
{
get<0>(*this) = AgentId;
get<1>(*this) = AgentIp;
}
long long getAgentId() const { return get<0>(*this); }
void setAgentId(const long long& AgentId) { get<0>(*this) = AgentId; }
string getAgentIp() const { return get<1>(*this); }
void setAgentIp(const string& AgentIp) { get<1>(*this) = AgentIp; }
};
Now I want to use this code:
int count = tuple_size<TR_AgentInfo>::value;
but gcc give this error:
error: incomplete type std::tuple_size<TR_AgentInfo> used in nested name specifier
now what can I do ?
If you just want your one class to work with std::tuple_size
, you can simply provide a specialization:
namespace std
{
template<> struct tuple_size<TR_AgentInfo>
{
static const size_t value = 2;
// alternatively, `tuple_size<tuple<long long, string>>::value`
// or even better, `tuple_size<TR_AgentInfo::tuple_type>::value`, #1
};
}
You are expressly allowed to add specializations to the namespace std
, precisely for situations like yours.
If your actual class is itself templated, you can simply replace 2
by an appropriate construction. For example, for suggestion #1 you could add a typedef for tuple_type
to your class. There are many ways to skin this cat.
If you have an instance of TR_AgentInfo
kicking around, you can use function template type deduction to make it friendlier, like so:
template <typename... T>
std::size_t get_tuple_size(std::tuple<T...> const &)
{
return sizeof...(T);
}
and call
TR_AgentInfo info;
int count = get_tuple_size(info);
otherwise you need to use proper metaprogramming to get at the base class, but facilities are available.