I've tried searching for this but every term I think of ends up with totally unrelated results.
I have a function (template) that takes a pointer-to-member as a parameter, but I cannot seem to implicitly treat the member being pointed to as const. Using const_cast works, but I'd like to avoid having to explicitly call it if I can.
struct MyStruct
{
int *_array;
int _size;
};
template<typename C, typename T>
void DoSomething(T* C::* arr, int siz)
{
// do some read-only stuff with the member here
}
template<typename C, typename T>
void ConstDoSomething(T* C::* arr, int siz)
{
DoSomething<C, T const>(arr, siz);
// DoSomething<C, T const>(const_cast<T const* C::*>(arr), siz); // works
}
MyStruct ms;
ConstDoSomething<MyStruct const, int>(&MyStruct::_array, ms._size); // note: cannot convert ‘arr’ (type ‘int* MyStruct::*’) to type ‘const int* MyStruct::*’
This is a simplified example that demonstrates the problem I'm having with a more complex class tree. I'm trying to avoid the cast because it would be required by the calling code (e.g., the person using the class template(s)).
UPDATE: When I first posted this I accidentally used a code sample that didn't generate the same error. It took me a fair amount of testing to determine the root cause, which was that I'm adding the const qualifier in the template arguments. The above sample now properly demonstrates the behavior I'm using.
What compiler do you use? I've tried your code Visual Studio 2012 and 2013 and it was compiled without any warnings or errors.
Either way - you should try const_cast instead of static_cast when you are playing with constness
In lieu of a better solution (for now at least), I'm creating a separate overload to accept a pointer-to-non-const-member and then use const_cast to call the originating methods.
As noted, the sample above was for simplicity and clarity's sake, but in actuality I am using several class templates, each inheriting from the other, and so forth. This has resulted in the following rather ugly solution:
// C = containing class (for pointer-to-members, std::nullptr_t if none)
// T = type of data being referenced
template<typename _C, typename _T> struct MakeMemberPointer // STL doesn't provide this??
{
public:
typedef _T _C::* Type;
};
// Note: base-class template has specialization for C == std::nullptr_t
typedef typename std::conditional<std::is_same<C, decltype(nullptr)>::value,
T const* C::*,
T const*
>::type N;
typedef typename std::conditional<std::is_member_pointer<T>::value,
typename MakeMemberPointer<
C,
typename std::add_pointer<
typename std::remove_const<
typename std::remove_reference<
decltype(*(static_cast<C*>(nullptr)->*static_cast<N>(nullptr))) // T const&
>::type // reference removed -> T const
>::type // const removed -> T
>::type // pointer added -> T*
>::Type, // member pointer -> T* C::*
typename std::add_pointer<typename std::remove_const<typename std::remove_pointer<N>::type>::type>::type
>::type NNoConst;
void DoSomething(N t) noexcept
{
}
void DoSomething(NNoConst t) noexcept
{
DoSomething(const_cast<N>(t));
}
The class containing all of this is a const-only class derived from a non-const base class (but used here with const members due to template arguments). Declaring all this inside the class is highly preferable (to me) over having to use const_cast in the calling code, but I still don't see why gcc isn't allowing this conversion implicitly (after all, it's just adding const qualifiers!!).
Related
I'm using the add_const typetrait in a scenario where it's applied on a forwarding reference type. Everything looked like no constness was added to the type so I made a small example to verify that was the case (PrintType is an incomplete type that will cause a compilation error, forcing the compiler to spit out the name of the template argument in the error message) :
#include <iostream>
#include <type_traits>
#include <complex>
template <class T>
struct PrintType;
template <class T>
void f(T&& arg)
{
PrintType<std::add_const_t<decltype(arg)>> local;
(void)local;
}
int main()
{
std::complex<double> co;
f(co);
}
The error message says :
main.cpp: In instantiation of 'void f(T&&) [with T = std::complex<double>&]':
main.cpp:20:9: required from here
main.cpp:12:48: error: 'PrintType<std::complex<double>&> local' has incomplete type
PrintType<std::add_const_t<decltype(arg)>> local;
ie the trait transformed my type to T = std::complex<double>& instead of T = std::complex<double> const&
The type trait works as expected. You should consider what you are attempting to do, which is to add constness to a reference. You can't rebind a reference (it's not mutable), so essentially any reference is a const reference
T& == T& const
What I suppose you expect to do is to create a reference to a const type (which reminds me of the const iterator vs const_iterator thingy) which cant' be done this way, for the same reason you can't typedef a reference type to a reference to a const type this way :
typedef T& ref_t;
typedef const ref_t const_ref_t; // This is not T const& !!
To sum up, adding const to a reference type makes it a const reference (which is the same as a reference) and not a reference to a const type
For situations like these, it can be useful to have a type trait that transfers the reference to a new type. This can complement another trait that does the same for const and volatile, implemented almost identically. In your case, you should only need to worry about lvalue references if you use T instead of decltype(arg). However, if using a lambda, you definitely do need to worry about rvalue references as well.
Here is a sample implementation:
template<typename T, bool ApplyLvalueRef, bool ApplyRvalueRef>
struct apply_ref {
static_assert(!(ApplyLvalueRef && ApplyRvalueRef), "Improper use: T cannot be & and &&");
using possibly_lref = std::conditional_t<
ApplyLvalueRef,
std::add_lvalue_reference_t<T>,
T
>;
using type = std::conditional_t<
ApplyRvalueRef,
std::add_rvalue_reference_t<possibly_lref>,
possibly_lref
>;
};
template<typename From, typename To>
struct transfer_ref : apply_ref<To, std::is_lvalue_reference<From>{}, std::is_rvalue_reference<From>{}> {};
template<typename From, typename To>
using transfer_ref_t = typename transfer_ref<From, To>::type;
At first glance, it seems a bit silly to have separate booleans for lvalue vs. rvalue. However, this allows for applying neither. There should never be a situation in which both are true, and this is enforced by the static assertion.
Now we can easily write the function:
template <class T>
void f(T&& arg)
{
using with_const = std::add_const_t<std::remove_reference_t<T>>;
PrintType<transfer_ref_t<T, with_const>> local;
(void)local;
}
Since we cannot apply const to a reference, we must strip it, add const to the referred type, and then add the reference back.
I have the following snipped of code, which does not compile.
#include <iostream>
struct A {
void foo() {}
};
struct B : public A {
using A::foo;
};
template<typename U, U> struct helper{};
int main() {
helper<void (A::*)(), &A::foo> compiles;
helper<void (B::*)(), &B::foo> does_not_compile;
return 0;
}
It does not compile since &B::foo resolves to &A::foo, and thus it cannot match the proposed type void (B::*)(). Since this is part of a SFINAE template that I am using to check for a very specific interface (I'm forcing specific argument types and output types), I would like for this to work independently of inheritances, while keeping the check readable.
What I tried includes:
Casting the second part of the argument:
helper<void (B::*)(), (void (B::*)())&B::foo> does_not_compile;
This unfortunately does not help as the second part is now not recognized as a constant expression, and fails.
I've tried assigning the reference to a variable, in order to check that.
constexpr void (B::* p)() = &B::foo;
helper<void (B::* const)(), p> half_compiles;
This code is accepted by clang 3.4, but g++ 4.8.1 rejects it, and I have no idea on who's right.
Any ideas?
EDIT: Since many comments are asking for a more specific version of the problem, I'll write it here:
What I'm looking for is a way to explicitly check that a class respects a specific interface. This check will be used to verify input arguments in templated functions, so that they respect the contract that those functions require, so that compilation stops beforehand in case the class and a function are not compatible (i.e. type traits kind of checking).
Thus, I need to be able to verify return type, argument type and number, constness and so on of each member function that I request. The initial question was the checking part of the bigger template that I'm using to verify matches.
A working solution to your problem as posted at https://ideone.com/mxIVw3 is given below - see also live example.
This problem is in a sense a follow-up of Deduce parent class of inherited method in C++. In my answer, I defined a type trait member_class that extracts a class from a given pointer to member function type. Below we use some more traits to analyse and then synthesize back such a type.
First, member_type extracts the signature, e.g. void (C::*)() gives void():
template <typename M> struct member_type_t { };
template <typename M> using member_type = typename member_type_t <M>::type;
template <typename T, typename C>
struct member_type_t <T C::*> { using type = T;};
Then, member_class extracts the class, e.g. void (C::*)() gives C:
template<typename>
struct member_class_t;
template<typename M>
using member_class = typename member_class_t <M>::type;
template<typename R, typename C, typename... A>
struct member_class_t <R(C::*)(A...)> { using type = C; };
template<typename R, typename C, typename... A>
struct member_class_t <R(C::*)(A...) const> { using type = C const; };
// ...other qualifier specializations
Finally, member_ptr synthesizes a pointer to member function type given a class and a signature, e.g. C + void() give void (C::*)():
template <typename C, typename S>
struct member_ptr_t;
template <typename C, typename S>
using member_ptr = typename member_ptr_t <C, S>::type;
template <typename C, typename R, typename ...A>
struct member_ptr_t <C, R(A...)> { using type = R (C::*)(A...); };
template <typename C, typename R, typename ...A>
struct member_ptr_t <C const, R(A...)> { using type = R (C::*)(A...) const; };
// ...other qualifier specializations
The two previous traits need more specialization for different qualifiers to be more generic, e.g. const/volatile or ref-qualifiers. There are 12 combinations (or 13 including data members); a complete implementation is here.
The idea is that any qualifiers are transferred by member_class from the pointer-to-member-function type to the class itself. Then member_ptr transfers qualifiers from the class back to the pointer type. While qualifiers are on the class type, one is free to manipulate with standard traits, e.g. add or remove const, lvalue/rvalue references, etc.
Now, here is your is_foo test:
template <typename T>
struct is_foo {
private:
template<
typename Z,
typename M = decltype(&Z::foo),
typename C = typename std::decay<member_class<M>>::type,
typename S = member_type<M>
>
using pattern = member_ptr<C const, void()>;
template<typename U, U> struct helper{};
template <typename Z> static auto test(Z z) -> decltype(
helper<pattern<Z>, &Z::foo>(),
// All other requirements follow..
std::true_type()
);
template <typename> static auto test(...) -> std::false_type;
public:
enum { value = std::is_same<decltype(test<T>(std::declval<T>())),std::true_type>::value };
};
Given type Z, alias template pattern gets the correct type M of the member pointer with decltype(&Z::foo), extracts its decay'ed class C and signature S, and synthesizes a new pointer-to-member-function type with class C const and signature void(), i.e. void (C::*)() const. This is exactly what you needed: it's the same with your original hard-coded pattern, with the type Z replaced by the correct class C (possibly a base class), as found by decltype.
Graphically:
M = void (Z::*)() const -> Z + void()
-> Z const + void()
-> void (Z::*)() const == M
-> SUCCESS
M = int (Z::*)() const& -> Z const& + int()
-> Z const + void()
-> void (Z::*)() const != M
-> FAILURE
In fact, signature S wasn't needed here, so neither was member_type. But I used it in the process, so I am including it here for completeness. It may be useful in more general cases.
Of course, all this won't work for multiple overloads, because decltype doesn't work in this case.
If you simply want to check the existence of the interface on a given type T, then there're better ways to do it. Here is one example:
template<typename T>
struct has_foo
{
template<typename U>
constexpr static auto sfinae(U *obj) -> decltype(obj->foo(), bool()) { return true; }
constexpr static auto sfinae(...) -> bool { return false; }
constexpr static bool value = sfinae(static_cast<T*>(0));
};
Test code:
struct A {
void foo() {}
};
struct B : public A {
using A::foo;
};
struct C{};
int main()
{
std::cout << has_foo<A>::value << std::endl;
std::cout << has_foo<B>::value << std::endl;
std::cout << has_foo<C>::value << std::endl;
std::cout << has_foo<int>::value << std::endl;
return 0;
}
Output (demo):
1
1
0
0
Hope that helps.
Here's a simple class that passes your tests (and doesn't require a dozen of specializations :) ). It also works when foo is overloaded. The signature that you wish to check can also be a template parameter (that's a good thing, right?).
#include <type_traits>
template <typename T>
struct is_foo {
template<typename U>
static auto check(int) ->
decltype( static_cast< void (U::*)() const >(&U::foo), std::true_type() );
// ^^^^^^^^^^^^^^^^^^^
// the desired signature goes here
template<typename>
static std::false_type check(...);
static constexpr bool value = decltype(check<T>(0))::value;
};
Live example here.
EDIT :
We have two overloads of check. Both can take a integer literal as a parameter and because the second one has an ellipsis in parameter list it'll never be the best viable in overload resolution when both overloads are viable (elipsis-conversion-sequence is worse than any other conversion sequence). This lets us unambiguously initialize the value member of the trait class later.
The second overload is only selected when the first one is discarded from overload set. That happens when template argument substitution fails and is not an error (SFINAE).
It's the funky expression on the left side of comma operator inside decltype that makes it happen. It can be ill-formed when
the sub-expression &U::foo is ill-formed, which can happen when
U is not a class type, or
U::foo is inaccesible, or
there is no U::foo
the resulting member pointer cannot be static_cast to the target type
Note that looking up &U::foo doesn't fail when U::foo itself would be ambiguous. This is guaranteed in certain context listed in C++ standard under 13.4 (Address of overloaded function, [over.over]). One such context is explicit type conversion (static_cast in this case).
The expression also makes use of the fact that T B::* is convertible to T D::* where D is a class derived from B (but not the other way around). This way there's no need for deducing the class type like in iavr's answer.
value member is then initialized with value of either true_type or false_type.
There's a potential problem with this solution, though. Consider:
struct X {
void foo() const;
};
struct Y : X {
int foo(); // hides X::foo
};
Now is_foo<Y>::value will give false, because name lookup for foo will stop when it encounters Y::foo. If that's not your desired behaviour, consider passing the class in which you wish to perform lookup as a template parameter of is_foo and use it in place of &U::foo.
Hope that helps.
I suggest using decltype to generically determine the type of the member function pointers:
helper<decltype(&A::foo), &A::foo> compiles;
helper<decltype(&B::foo), &B::foo> also_compiles;
It may seem like a DRY violation, but repeating the name is fundamentally no worse than specifying the type separately from the name.
I'm been grinding my head against an idea that is simple enough in my head, but I can't figure out how to implement in C++.
Normally, I can declare a class with a conversion operator like in this simple example:
class Foo
{
private:
int _i;
public:
Foo( int i ) : _i(i) { }
operator int( ) const
{
return i;
}
};
So now I can write awesome stuff like
int i = Foo(3);
But in my particular case, I would like to provide an operator for converting an object to a function pointer (e.g. converting a Bar instance to a int(*)(int, int) function pointer). Here's what I initially tried:
class Bar
{
private:
int (*_funcPtr)(int, int);
public:
Bar( int (*funcPtr)(int, int) ) : _funcPtr(funcPtr) { }
operator int(*)(int, int) ( ) const
{
return _funcPtr;
}
};
But the operator function fails to compile, with these errors being generated:
expected identifier before '*' token
'<invalid-operator>' declared as a function returning a function
I have also tried simple variations on the above, such as surrounding the return type in parenthesis, but all these ideas have also failed.
Does anyone know what the syntax is for declaring a conversion-to-function-pointer operator method, or whether it is even possible to do so?
Note: I am compiling this with Code::Blocks using GCC 4.5.2. Answers involving some of the new C++0x concepts are also welcome.
Edit
In my strive for simplifying the example, I unintentionally left out one detail. It's a bit weird, but rather than strictly returning an int(*)(int,int) pointer, the conversion operator is intended to be templated:
template<typename ReturnType, typename ArgType1, typename ArgType2>
operator ReturnType(*)(ArgType1, ArgType2) ( ) const
{
// implementation is unimportant here
}
As far as I know, I no longer cannot typedef such a type. This clearly makes things much more clumsy, but I hope that there is still a way.
Since you must know:
(*operator int() const)(int, int)
{
return _funcPtr;
}
(Fixed. Again.)
Update: I've been informed by Johannes Schraub and Luc Danton that this syntax is in fact not valid, and that you really must use a typedef. Since you say that typedefs aren't an option, here's a helper class that can wrap your typedef:
template<typename R, typename A1, typename A2>
struct MakeFunctionType
{
typedef R(*type)(A1, A2);
};
template<typename R, typename A1, typename A2>
operator typename MakeFunctionType<R, A1, A2>::type () const
{
// implementation is unimportant here
}
Use a typedef. It's easier to read, anyway:
class Bar
{
public:
typedef int (*fptr_t)(int, int);
Bar(fptr_t funcPtr) : _funcPtr(funcPtr) { }
operator fptr_t() const
{
return _funcPtr;
}
private:
fptr_t _funcPtr;
};
[edit]
For your template case I do not see how to use a typedef. #Kerrik gives the (messy) version of the syntax that should work.
EDIT:
Since your class has a non template function pointer assigned at constuction:
private:
int (*_funcPtr)(int, int);
It is not at all possible to later convert that to a function pointer of any type.
I will therefore assume that you meant a template class member operator overload, not a class template member operator overload.
Template version:
template<typename ReturnType, typename ArgType1, typename ArgType2>
class Bar {
public:
typedef ReturnType (*fptr_t)(ArgType1, ArgType2);
operator fptr_t ( ArgType1 arg1, ArgType2 arg2 ) const
{
// implementation is unimportant here
}
//etc...
};
Then used like this:
//create functor to some function called myfunc
Bar::fptr_t func_ptr = Bar<int, int, int>(&myfunc);
//call functor
int i = func_ptr(1,2);
If you want to make the code readable, you need to use a typedef. I don't even use functions pointers without typedef'ing them, the syntax is too horrid.
Goal:
template<typename ReturnType, typename ArgType1, typename ArgType2>
operator ReturnType(*)(ArgType1, ArgType2) ( ) const
{
return 0;
}
Path:
// 1: helper structure
template <typename R, typename A0, typename A1>
struct helper {
typedef R (*type)(A0,A1);
};
// 2: operator
template <typename R, typename A0, typename A1>
operator typename helper<R, A0, A1>::type() const {
return 0;
}
Check it out on ideone!
In C++11, it is possible to use an alias template to convert to any function, bypassing the need for custom type trait structs.
class Bar
{
private:
template<typename ReturnType, typename ArgType1, typename ArgType2>
using funcptr = ReturnType(*)(ArgType1, ArgType2);
public:
template<typename ReturnType, typename ArgType1, typename ArgType2>
operator funcptr<ReturnType, ArgType1, ArgType2> ( ) const;
};
To limit this to just int(*)(int, int), we can use SFINAE or static_assert.
The following works in GCC:
template<typename ReturnType, typename ArgType1, typename ArgType2>
operator decltype((ReturnType(*)(ArgType1, ArgType2)) nullptr)() const
{
// ...
}
I have this template class:
template <class Tin, class Tout>
class Foo
{
Tin input;
Tout output;
static inline void __ensure_type_consistency
{
int16_t* p = (int16_t *)0;
// uint16_t* p1 = p;
Tin* check_type_in = p;
Tout* check_type_out = p;
}
public:
...
}
I want to make sure that Tin and Tout are both typedef'd to type int16_t and not some other type. (NOTE: please read the full question before jumping to conclusions)
If I uncomment the commented line, I get an error as expected; the compiler doesn't allow pointers of different types to be assigned to each other without a cast:
"src\foo.h", line 47: error #145: a value of type "int16_t *"
cannot be used to initialize an entity of type "uint16_t *"
But if I keep it commented out, and I instantiate:
Foo<uint16_t, int32_t> illegalFoo;
I don't get compiler errors, even though the same type of check is used (creating an incompatible pointer assignment in a static function that is never actually called, but which should cause compiler errors)
Is there a way to create a static compile-time type consistency check? Why doesn't the one I'm using work?
NOTE: Ignore for a moment the obvious solution of just getting rid of the template parameters. That would "solve" this problem, but there are some out-of-band things going on here with my debugging tools where typedefs are being used to impart important metadata: I want to ensure that Foo.input is of type Tin where Tin is either an int16_t or a typedef that resolves as an int16_t, and similarly with Foo.output and Tout. There are slight differences from the perspective of my debugging tools, where typedef'd types and their base type can be distinguished, even though within a C++ program they are identical.
edit: by the way, this is an embedded system, and I can't use Boost. It's also not C++0x.
You can use the is_same type trait in a static_assert. The C++0x would look like:
static_assert(std::is_same<Tin, std::int16_t>::value &&
std::is_same<Tout, std::int16_t>::value, "o noez");
You can find both the is_same type trait and the static assert in Boost as well. Even if you are compiling for an embedded system, it is straightforward to extract just the type traits and static assert headers from Boost and neither of those libraries have any runtime overhead.
One simple way:
template <class, class> class Foo;
template <>
class Foo<int16_t, int16_t> {
...
};
The other way, if your conditions are actually more complicated, is to use BOOST_STATIC_ASSERT from Boost or static_assert from C++0x. Since you wanted non-Boost options and C++0x may not work, here's something more similar to what you posted in your example:
(void)(true ? (int16_t**)0 : (Tin**)0);
and the same for Tout. That needs to be in some method that is either called or has its address taken (the idiom for doing that is at the end of the Boost.Concept_check implementation documentation). If you want something like the is_same/static_assert solution others have posted but without Boost or C++0x, try:
template <class, class> struct types_valid {static const int value = -1;};
template <> struct types_valid<int16_t, int16_t> {static const int value = 1;};
Then put static char foo[types_valid<Tin, Tout>::value]; in your class outside of any methods. I believe you won't need to actually define foo as long as you don't refer to it anywhere.
While you can't use boost or C++1x, you can make your own is_same compile-time type comparator and hack up some poor-man's compile-time assertion
// Beware, brain-compiled code ahead!
template< typename T1, typename T2>
struct is_same { static const bool result = false; };
template< typename T >
struct is_same<T,T> { static const bool result = true; };
template< bool Condition, typename Dummy = void >
struct static_assert {
typedef bool result;
};
template<typename IntentionalError>
struct static_assert<false,IntentionalError> {
typedef typename IntentionalError::does_not_exist result;
};
and use it like this:
template <class Tin, class Tout>
class Foo
{
Tin input;
Tout output;
typedef typename static_assert<is_same<Tin ,int16_t>::result>::result Tin_test;
typedef typename static_assert<is_same<Tout,int16_t>::result>::result Tout_test;
typedef typename static_assert<is_same<Tout,Tout >::result>::result Tout_test;
// ...
};
Your method works, but you must actually call __ensure_type_consistency ( ) somewhere for the compiler to throw the error. If the method is never called, then the compiler thinks it can ignor it.
I just tried it in VC++ 2010, and it works.
Are you using GCC? Try putting using attribute ((used)) on __ensure_type_consistency.
You could use Boost Concept Checks:
BOOST_CONCEPT_ASSERT((boost::Integer<Tin>));
BOOST_CONCEPT_ASSERT((boost::Integer<Tout>));
See http://www.boost.org/doc/libs/1_45_0/libs/concept_check/using_concept_check.htm
I've adapted several responses to this question, and this seems to do the trick nicely:
A helper class:
template <typename T1, typename T2>
struct TypeConsistency
{
private:
static inline void checkfunction()
{
T1* p1 = (T1 *)0;
T2* p2 = p1;
}
public:
static inline void check() { checkfunction; }
/* The above line does nothing at runtime,
* but takes the address of checkfunction(),
* which causes a compile-time type check.
*/
};
Applying this in my foo class:
template <class Tin, class Tout>
class Foo
{
Tin input;
Tout output;
public:
Foo() {
TypeConsistency<int16_t, Tin>::check();
TypeConsistency<int16_t, Tout>::check();
}
...
}
I have a subset of a pointer class that look like:
template <typename T>
struct Pointer
{
Pointer();
Pointer(T *const x);
Pointer(const Pointer &x);
template <typename t>
Pointer(const Pointer<t> &x);
operator T *() const;
};
The goal of the last constructor is to allow to pass a Pointer of a subclass, or basically any type that is implicitly convertable to T *. This actual rule is only enforced by the definition of the constructor and the compiler can't actually figure it out by the declaration alone. If I drop it, and try to pass a Pointer<Sub> to a constructor of Pointer<Base>, I get a compile error, despite of the possible path through operator T *().
While it solves the above problem, it creates another one. If I have an overloaded function whose one overload takes a Pointer<UnrelatedClass> and the other takes Pointer<BaseClass>, and I try to invoke it with a Pointer<SubClass>, I get an ambiguity between the two overloads, with the intention, ofcourse, that the latter overload will be called.
Any suggestions? (Hopefully I was clear enough)
The cure for your problem is called SFINAE (substitution failure is not an error)
#include "boost/type_traits/is_convertible.hpp"
#include "boost/utility/enable_if.hpp"
template<typename T>
class Pointer {
...
template<typename U>
Pointer(const Pointer<U> &x,
typename boost::enable_if<
boost::is_convertible<U*,T*>
>::type* =0)
: ...
{
...
}
...
};
If U* is convertible to T* the enable_if will have a typedef member type defaulting to void. Then, everything is fine. If U* is not convertible to T* this typedef member is missing, substitution fails and the constructor template is ignored.
This solves your conversion and ambiguity problems.
In response to the comment: is_convertible looks something like this:
typedef char one; // sizeof == 1 per definition
struct two {char c[2];}; // sizeof != 1
template<typename T, typename U>
class is_convertible {
static T source();
static one sink(U);
static two sink(...);
public:
static const bool value = sizeof(sink(source()))==1;
};
Try to make the constructor in question explicit, e.g.:
template <typename t>
explicit Pointer(const Pointer<t> &x);
And/or remove the operator T *() const; - I think this one will also create an ambiguity.
EDIT
Check the std::auto_ptr interface, and compare with yours. At least they solved the ambiguity.