Re: SFINAE help
On Aug 18, 6:08 am, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
wrote:
Tim H wrote:
I have a template class 'Property' that has a ValueType typedef in it.
I have a method of another class that looks like this:
template<class Tkey>
const typename Tkey::ValueType &GetProperty() const { ... }
I want to support Properties with void ValueType. I added a
specialization of Property and that works. what fails is when code
calls the above GetProperty<VoidProperty>() method. I get a "no
matching function" error (g++).
It looks like SFINAE is correctly determining that a 'const void &' is
an error. The error message is not very helpful, though.
How can I use SFINAE (or other tricks) to make calls to
GetProperty<VoidProperty>() blow up in a more obvious manner?
Tim H wrote:
> I have a template class 'Property' that has a ValueType typedef in i=
t.
>
> I have a method of another class that looks like this:
>
> template<class Tkey>
> const typename Tkey::ValueType &GetProperty() const { ..=
.. }
>
> I want to support Properties with void ValueType. I added a
> specialization of Property and that works. what fails is when cod=
e
> calls the above GetProperty<VoidProperty>() method. I get a "no
> matching function" error (g++).
>
> It looks like SFINAE is correctly determining that a 'const void &' =
is
> an error. The error message is not very helpful, though.
>
> How can I use SFINAE (or other tricks) to make calls to
> GetProperty<VoidProperty>() blow up in a more obvious manner?
There is no SFINAE involved because you instantiate the function template
_explicitly_.
SFINAE works while the compiler is building a set of viable function over=
loads.
In doing so it also tries to _implicitly_ instantiate function templates.=
If
function template instantiation fails when the template arguments are
substituted with particular types, that Substitution Failure Is Not An Er=
ror,
the function template is simply disregarded and no compiler error produce=
d.
Your example can be made to work without SFINAE. Something like that:
template<class T>
struct MakeRefToConst
{
typedef T const& type;
};
template<>
struct MakeRefToConst<void>
{
typedef void type; // don't make references to void
};
cute!
template<class Tkey>
typename MakeRefToConst<typename Tkey::ValueType>::type GetPro=
perty();
This is a class method, in my situation, which may matter. The
question I have is - what does the body of this function look like?
The generic implementation of this ends with
return specific->GetValue();
on which the compiler complains about "return-statement with a value,
in function returning 'void'"
How can I provide an alternate body for void ValueType that does not
try to return a value?
struct A
{
typedef int ValueType;
};
struct B
{
typedef void ValueType;
};
int main()
{
GetProperty<A>();
GetProperty<B>();
}
Instead of MakeRefToConst<> you can use boost type traits.http://www.boos=
t.org/doc/libs/1_39_0/libs/type_traits/doc/html/boost_...
Max