I am mildy confused by the following situation where I have a specialization enabled on is_base_of
.
is_base_of
requires the full definition of the type that is being checked to be available. However, the type that is being specialized is being used as a member of the type who's base is being checked - so both need to be defined before the other, and I cannot forward declare the inheritance relationship.
What is confusing is that if I instead tag the base and enable on this tag existing, it works. Surely for this to work, the inheritance relationship must be known at this point. so why doesn't is_base_of
work without the full definition being available?
#define OPTION 1 // OPTION 2 : broken, OPTION 1 : works
#include <iostream>
#include <type_traits>
using namespace std;
template <typename body_type,typename Enable=void>
struct limb
{
const char* value = "regular limb";
};
template <typename SomeT>
struct body
{
typedef SomeT type;
#if OPTION ==1
struct body_tag{};
#endif
};
#if OPTION ==2
template <typename body_type>
struct limb < body_type, typename std::enable_if < std::is_base_of< body<typename body_type::type>, body_type>::value>::type>
{
const char* value = "fat limb";
};
#else
template <typename body_type>
struct limb < body_type, std::void_t<typename body_type::body_tag> >
{
const char* value = "fat limb";
};
#endif
template <typename SomeT>
struct fatbody : body<SomeT>
{
limb<fatbody> arm;
typedef SomeT type;
};
template <typename SomeT>
struct slimbody
{
limb<slimbody> arm;
typedef SomeT type;
};
int main() {
#if OPTION == 1
// to check the enable cond used on OPTION 2 is correct
typedef fatbody<int> body_type;
typedef slimbody<int> body_type2;
std::cout << std::is_base_of<body<typename body_type::type>,body_type >::value << std::endl;
std::cout << std::is_base_of<body<typename body_type2::type>,body_type2 >::value << std::endl;
#endif
std::cout << slimbody<int>().arm.value << std::endl;
std::cout << fatbody<int>().arm.value << std::endl;
return 0;
}
Aucun commentaire:
Enregistrer un commentaire