What Is the Status of N2965 - Std::Bases and Std::Direct_Bases

What is the status of N2965 - std::bases and std::direct_bases?

As far as I can tell this was rejected we can see this from N3296: C++ FCD Comment Status Rev 6 which has the following comment:

Paper n2965 was largely rejected after the last CD on the grounds there was no associated national body comment, so I am submitting a national body comment this time.

and the disposition ended up being:

REJECTED

There is no consensus to adopt this proposal at this time

We can find a comment from Jonathan Wakely which points us to the gcc patches email about implementing N2965 into gcc and he notes that there is no TR2 anymore.

I don't see any follow-up proposals for this

Status of std::bases and std::direct_bases

The original proposal for std::bases was rejected, in part because it arrived too late for a then immediately upcoming new standard. Seems like that specific proposal has not resurfaced again.

However, there is a new and more general proposal P0194 Static reflection that includes ways to not only interrogate base classes, but also has a much wider target.

Right now, that proposal contains some types that seems to do something like what the std::bases proposal suggested:

template <Class T> struct get_public_base_classes;
template <Class T> struct get_accessible_base_classes;
template <Class T> struct get_base_classes;

However (again), in Herb Sutter's latest report from the ISO C++ meeting he projects these kinds of features not to appear in C++20, but perhaps in a future C++23 standard.

Sample Image

using tr2::direct_bases get nth element of result

You can use this simple metafunction to turn the typelist into an std::tuple:

#include <tr2/type_traits>
#include <tuple>

template<typename T>
struct dbc_as_tuple { };

template<typename... Ts>
struct dbc_as_tuple<std::tr2::__reflection_typelist<Ts...>>
{
typedef std::tuple<Ts...> type;
};

At this point, you could work with it as you would normally work with a tuple. For instance, this is how you could retrieve elements of the type list:

struct A {};
struct B {};
struct C : A, B {};

int main()
{
using namespace std;

using direct_base_classes = dbc_as_tuple<tr2::direct_bases<C>::type>::type;

using first = tuple_element<0, direct_base_classes>::type;
using second = tuple_element<1, direct_base_classes>::type;

static_assert(is_same<first, A>::value, "Error!"); // Will not fire
static_assert(is_same<second, B>::value, "Error!"); // Will not fire
}

Finding base class at compile time

gcc supports this. See

  • Kerrek's answer
  • tr2/type_traits
  • Andy Prowl's code example
  • n2965
  • What is the status of N2965 - std::bases and std::direct_bases?
  • How to query for all base classes of a class at compile time?

n2965 provides an example.

This simple examples illustrates the results of these type traits. In
the Suppose we have the following class hierarchy:

class E {};
class D {};
class C : virtual public D, private E {};
class B : virtual public D, public E {};
class A : public B, public C {};

It follows that bases<A>::type is tuple<D, B, E, C, E>

Similarly, direct_bases<A>::type is tuple<B, C>

Andy Prowl's code example is as follows:

#include <tr2/type_traits>
#include <tuple>

template<typename T>
struct dbc_as_tuple { };

template<typename... Ts>
struct dbc_as_tuple<std::tr2::__reflection_typelist<Ts...>>
{
typedef std::tuple<Ts...> type;
};

struct A {};
struct B {};
struct C : A, B {};

int main()
{
using namespace std;

using direct_base_classes = dbc_as_tuple<tr2::direct_bases<C>::type>::type;

using first = tuple_element<0, direct_base_classes>::type;
using second = tuple_element<1, direct_base_classes>::type;

static_assert(is_same<first, A>::value, "Error!"); // Will not fire
static_assert(is_same<second, B>::value, "Error!"); // Will not fire
}

Check if the class has any base class in C++ in compile time

As mentioned in comments you can't do exactly this in standard C++. The closest you get from std library is std::is_base_of, but it is for testing a specific base class.

But as mentioned here GCC has std::tr2::bases (and std::tr2::direct_bases) that solves your question for a generic "has any base" assertion. These came from the N2965 proposal and unfortunately was rejected for std C++.

Here's a sample code showing how you can use this GCC extension to assert just what you want:

#include <tr2/type_traits>

class B {};

class X : public B {};
static_assert(std::tr2::bases<X>::type::empty(),"X");
// doesn't compile because X bases tuple returned is not empty

class Y {};
static_assert(std::tr2::bases<Y>::type::empty(),"Y");

#include <iostream>
using namespace std;

int main() {
return 0;
}


Related Topics



Leave a reply



Submit