Re: Can a class type be considered both incomplete and abstract?
Consider the following fragment of an existing std::tr1::is_function
implementation:
template<typename _Tp>
struct __in_array
: public __sfinae_types
{
private:
template<typename _Up>
static __one __test(_Up(*)[1]);
template<typename>
static __two __test(...);
public:
static const bool __value = sizeof(__test<_Tp>(0)) == 1;
};
template<typename _Tp>
struct is_function
: public integral_constant<bool, !(__in_array<_Tp>::__value
|| __is_union_or_class<_Tp>::value
|| is_reference<_Tp>::value
|| is_void<_Tp>::value)>
{ };
There is no intention to create an array object here. __in_array is
the helper that checks whether a type under test is a valid array
element type. If the check is successful then the type is not a
function. This implementation has two potential defects. First, the
following example probably becomes ill-formed:
#include <type_traits>
struct Abstract;
int main()
{
enum { value = std::tr1::is_function<Abstract>::value };
}
struct Abstract
{
virtual void f() = 0;
};
If the overload resolution selects "static __one __test(_Up(*)[1])" we
have the use of type Abstract(*)[1] which is presumably not a valid
type.
Second, the violation of the rule "If two different points of
instantiation give a template specialization different meanings
according to the one definition rule (3.2), the program is ill-formed"
relative to specialization __in_array<Abstract> is possible. So, the
correct solution looks like this:
template<typename _Tp, bool _Is_union_or_class>
struct __in_array_or_abstract
: public __sfinae_types
{
private:
template<typename _Up>
static __one __test(_Up(*)[1]);
template<typename>
static __two __test(...);
public:
static const bool value = sizeof(__test<_Tp>(0)) == 1;
};
template <class _Tp>
struct __in_array_or_abstract<_Tp, true>
{
static const bool value = true;
};
template<typename _Tp>
struct is_function
: public integral_constant<bool,
!(__in_array_or_abstract<_Tp,
__is_union_or_class<_Tp>::value>::value
|| is_reference<_Tp>::value
|| is_void<_Tp>::value)>
{ };
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]