E
edd
Hello all,
Is there a way to determine whether a particular type supports the ->
operator at compile time?
I'm trying to write a template function (or a series of overloads)
that will yield the raw pointer at "the end of the arrow". For types
that support the operator, I have a reasonable solution, but I'd like
to have a null pointer returned if the operator isn't supported by a
particular object.
So far I have:
//----begin----
#include <memory>
#include <iostream>
template<typename Ptr, typename T>
Ptr pointer_from_arrowable(T *p) { return p; }
template<typename Ptr, typename Arrowable>
Ptr pointer_from_arrowable(Arrowable &a)
{
return pointer_from_arrowable<Ptr>(a.operator->());
}
int main()
{
std::auto_ptr<int> ap(new int(5));
int *p = pointer_from_arrowable<int *>(ap);
std::cout << *p << '\n'; // 5
return 0;
}
//----end----
I thought I might be able to use SFINAE to help the compiler choose an
overload that returns 0 when no operator-> exists, but I end up with
errors (MSVC8 and MinGW g++ 3.4.5) about ambiguous overloads (see end
of post):
//----begin----
#include <memory>
#include <iostream>
template<typename T>
struct mfn_pointer { typedef void (T::*type)(); };
template<typename Ptr, typename T>
Ptr pointer_from_arrowable(T *p) { return p; }
template<typename Ptr, typename Arrowable>
Ptr pointer_from_arrowable(
Arrowable &a,
typename mfn_pointer<Arrowable>::type sfinae =
(typename
mfn_pointer<Arrowable>::type)&Arrowable:perator->
)
{
return pointer_from_arrowable<Ptr>(a.operator->());
}
template<typename Ptr, typename Arrowable>
Ptr pointer_from_arrowable(Arrowable &a) { return 0; }
int main()
{
std::auto_ptr<int> ap(new int(5));
int *p = pointer_from_arrowable<int *>(ap);
std::cout << *p << '\n'; // 5
return 0;
}
//----end----
So is there any way to do what I want?
Here are the compiler errors I got when I attempted the SFINAE code:
MinGW g++ 3.4.5:
--------------------------------------------------
g++ -o arrow.o -c arrow.cpp -ggdb3 -Wall -Wextra -pedantic -ansi -O0 -
Wswitch -D _GLIBCXX_DEBUG
arrow.cpp: In function `int main()':
arrow.cpp:26: error: call of overloaded
`pointer_from_arrowable(std::auto_ptr<int>&)' is ambiguous
arrow.cpp:16: note: candidates are: Ptr
pointer_from_arrowable(Arrowable&, typename
mfn_pointer<Arrowable>::type) [with Ptr = int*, Arrowable =
std::auto_ptr<int>]
arrow.cpp:21: note: Ptr
pointer_from_arrowable(Arrowable&) [with Ptr = int*, Arrowable =
std::auto_ptr<int>]
error: system call returned unexpected exit-code 1
--------------------------------------------------
MSVC 8:
--------------------------------------------------
cl /Foarrow.obj /c arrow.cpp /nologo /Od /Zc:forScope,wchar_t /RTCc /
GR /RTCs /Zi /wd4996 /D _CRT_SECURE_NO_DEPRECATE /RTCu /EHsc /MTd /W3
arrow.cpp
arrow.cpp(26) : error C2668: 'pointer_from_arrowable' : ambiguous call
to overloaded function
arrow.cpp(21): could be 'Ptr
pointer_from_arrowable<int*,std::auto_ptr<_Ty>>(Arrowable &)'
with
[
Ptr=int *,
_Ty=int,
Arrowable=std::auto_ptr<int>
]
arrow.cpp(11): or 'Ptr
pointer_from_arrowable<int*,std::auto_ptr<_Ty>>(Arrowable &,void
(__thiscall std::auto_ptr<_Ty>::* )(void))'
with
[
Ptr=int *,
_Ty=int,
Arrowable=std::auto_ptr<int>
]
while trying to match the argument list '(std::auto_ptr<_Ty>)'
with
[
_Ty=int
]
error: system call returned unexpected exit-code 2
Is there a way to determine whether a particular type supports the ->
operator at compile time?
I'm trying to write a template function (or a series of overloads)
that will yield the raw pointer at "the end of the arrow". For types
that support the operator, I have a reasonable solution, but I'd like
to have a null pointer returned if the operator isn't supported by a
particular object.
So far I have:
//----begin----
#include <memory>
#include <iostream>
template<typename Ptr, typename T>
Ptr pointer_from_arrowable(T *p) { return p; }
template<typename Ptr, typename Arrowable>
Ptr pointer_from_arrowable(Arrowable &a)
{
return pointer_from_arrowable<Ptr>(a.operator->());
}
int main()
{
std::auto_ptr<int> ap(new int(5));
int *p = pointer_from_arrowable<int *>(ap);
std::cout << *p << '\n'; // 5
return 0;
}
//----end----
I thought I might be able to use SFINAE to help the compiler choose an
overload that returns 0 when no operator-> exists, but I end up with
errors (MSVC8 and MinGW g++ 3.4.5) about ambiguous overloads (see end
of post):
//----begin----
#include <memory>
#include <iostream>
template<typename T>
struct mfn_pointer { typedef void (T::*type)(); };
template<typename Ptr, typename T>
Ptr pointer_from_arrowable(T *p) { return p; }
template<typename Ptr, typename Arrowable>
Ptr pointer_from_arrowable(
Arrowable &a,
typename mfn_pointer<Arrowable>::type sfinae =
(typename
mfn_pointer<Arrowable>::type)&Arrowable:perator->
)
{
return pointer_from_arrowable<Ptr>(a.operator->());
}
template<typename Ptr, typename Arrowable>
Ptr pointer_from_arrowable(Arrowable &a) { return 0; }
int main()
{
std::auto_ptr<int> ap(new int(5));
int *p = pointer_from_arrowable<int *>(ap);
std::cout << *p << '\n'; // 5
return 0;
}
//----end----
So is there any way to do what I want?
Here are the compiler errors I got when I attempted the SFINAE code:
MinGW g++ 3.4.5:
--------------------------------------------------
g++ -o arrow.o -c arrow.cpp -ggdb3 -Wall -Wextra -pedantic -ansi -O0 -
Wswitch -D _GLIBCXX_DEBUG
arrow.cpp: In function `int main()':
arrow.cpp:26: error: call of overloaded
`pointer_from_arrowable(std::auto_ptr<int>&)' is ambiguous
arrow.cpp:16: note: candidates are: Ptr
pointer_from_arrowable(Arrowable&, typename
mfn_pointer<Arrowable>::type) [with Ptr = int*, Arrowable =
std::auto_ptr<int>]
arrow.cpp:21: note: Ptr
pointer_from_arrowable(Arrowable&) [with Ptr = int*, Arrowable =
std::auto_ptr<int>]
error: system call returned unexpected exit-code 1
--------------------------------------------------
MSVC 8:
--------------------------------------------------
cl /Foarrow.obj /c arrow.cpp /nologo /Od /Zc:forScope,wchar_t /RTCc /
GR /RTCs /Zi /wd4996 /D _CRT_SECURE_NO_DEPRECATE /RTCu /EHsc /MTd /W3
arrow.cpp
arrow.cpp(26) : error C2668: 'pointer_from_arrowable' : ambiguous call
to overloaded function
arrow.cpp(21): could be 'Ptr
pointer_from_arrowable<int*,std::auto_ptr<_Ty>>(Arrowable &)'
with
[
Ptr=int *,
_Ty=int,
Arrowable=std::auto_ptr<int>
]
arrow.cpp(11): or 'Ptr
pointer_from_arrowable<int*,std::auto_ptr<_Ty>>(Arrowable &,void
(__thiscall std::auto_ptr<_Ty>::* )(void))'
with
[
Ptr=int *,
_Ty=int,
Arrowable=std::auto_ptr<int>
]
while trying to match the argument list '(std::auto_ptr<_Ty>)'
with
[
_Ty=int
]
error: system call returned unexpected exit-code 2