 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Michael Fawcett Guest
|
Posted: Tue Oct 19, 2004 4:23 pm Post subject: enable_if and operator[] (or workaround) |
|
|
The following is producing a compiler error with MSVS 7.1 :
template <typename X, typename Y = X, typename Z = Y>
struct vec3
{
// operator[] will only be enabled if the typex == typey == typez
inline typename boost::enable_if<boost::mpl::and_
boost::is_same<Y, Z> >, X &>::type operator[](size_t idx);
inline typename boost::enable_if<boost::mpl::and_
boost::is_same<Y, Z> >, X const &>::type operator[](size_t idx) const;
};
int main(void)
{
vec3<float, int> a;
}
vec3_class.h(50): error C2039: 'type' : is not a member of
'boost::enable_if<Cond,T>'
with
[
Cond=boost::mpl::and_<boost::is_same,
T=float &
]
which would suggest that the compiler is doing more than just a syntax check
of the declaration. It's been a while since I've used enable_if, but isn't
this legal usage? Shouldn't I only get a compiler error if I attempt to use
operator[] with a class where X != Y or Y != Z?
Apologies if this should have gone to the boost mailing list.
Thanks,
Michael Fawcett
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Maxim Yegorushkin Guest
|
Posted: Wed Oct 20, 2004 9:40 pm Post subject: Re: enable_if and operator[] (or workaround) |
|
|
On 19 Oct 2004 12:23:20 -0400, Michael Fawcett <spam_mikef (AT) intelgames (DOT) com>
wrote:
| Quote: | The following is producing a compiler error with MSVS 7.1 :
template <typename X, typename Y = X, typename Z = Y
struct vec3
{
// operator[] will only be enabled if the typex == typey == typez
inline typename boost::enable_if
boost::is_same<Y, Z> >, X &>::type operator[](size_t idx);
inline typename boost::enable_if<boost::mpl::and_
boost::is_same<Y, Z> >, X const &>::type operator[](size_t idx) const;
};
|
The compiler is right.
SFINAE applies to function templates only. Here you've got a class template
with member functions and with no function templates. And these member
functions have ill-formed signatures when vec3's template arguments are not
of the same type.
--
Maxim Yegorushkin
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Peter Dimov Guest
|
Posted: Wed Oct 20, 2004 9:43 pm Post subject: Re: enable_if and operator[] (or workaround) |
|
|
"Michael Fawcett" <spam_mikef (AT) intelgames (DOT) com> wrote
| Quote: | The following is producing a compiler error with MSVS 7.1 :
template <typename X, typename Y = X, typename Z = Y
struct vec3
{
// operator[] will only be enabled if the typex == typey == typez
inline typename boost::enable_if
boost::is_same<Y, Z> >, X &>::type operator[](size_t idx);
inline typename boost::enable_if<boost::mpl::and_
boost::is_same<Y, Z> >, X const &>::type operator[](size_t idx) const;
};
int main(void)
{
vec3<float, int> a;
}
vec3_class.h(50): error C2039: 'type' : is not a member of
'boost::enable_if<Cond,T>'
with
[
Cond=boost::mpl::and_<boost::is_same,
T=float &
]
which would suggest that the compiler is doing more than just a syntax check
of the declaration. It's been a while since I've used enable_if, but isn't
this legal usage?
|
No, it's not. enable_if/SFINAE only works with function templates.
Your operator[] functions are ordinary member functions. They are
members of a class template, but this doesn't turn them into function
templates, and their declarations are instantiated when the definition
of their enclosing class template is instantiated. Their _definitions_
will only be instantiated upon first use, though, so you can put a
static assert inside.
HTH.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Motti Lanzkron Guest
|
Posted: Thu Oct 21, 2004 5:11 pm Post subject: Re: enable_if and operator[] (or workaround) |
|
|
Michael Fawcett wrote:
| Quote: | The following is producing a compiler error with MSVS 7.1 :
template <typename X, typename Y = X, typename Z = Y
struct vec3
{
// operator[] will only be enabled if the typex == typey == typez
inline typename boost::enable_if
boost::is_same<Y, Z> >, X &>::type operator[](size_t idx);
inline typename boost::enable_if<boost::mpl::and_
boost::is_same<Y, Z> >, X const &>::type operator[](size_t idx) const;
};
|
The way I understand things SFINAE only kicks in when selecting
between template functions, if the only option has substitution
failure that you get SFIAE [Substitution Failure Is An Error ;o)].
Maybe what you want is to inherit from a base class that either has or
doesn't have the required function.
Something like this.
template <class Derived, typename X, typename Y, typename Z>
struct vec3_helper {
// they differ no operator[]
};
template <class Derived, typename X>
struct vec3_helper<X, X, X>
{
// they're the same supply operator[]
A& operator[](size_t) {
// do stuff on static_cast<Derived*>(this)
}
A operator[](size_t) const;
};
Then you use:
template <typename X, typename Y = X, typename Z = Y>
struct vec3 : public vec3_helper<vec3, X, Y, Z>
{
};
Good luck.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
James Hopkin Guest
|
Posted: Thu Oct 21, 2004 5:16 pm Post subject: Re: enable_if and operator[] (or workaround) |
|
|
"Michael Fawcett" <spam_mikef (AT) intelgames (DOT) com> wrote
| Quote: |
It's been a while since I've used enable_if, but isn't
this legal usage? Shouldn't I only get a compiler error if I attempt to use
operator[] with a class where X != Y or Y != Z?
|
No, it only works for template functions, where the types are being
deduced. This is somewhat similar to a recent discussion:
<tinyurl.com/6xgsw>
James
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
David Abrahams Guest
|
Posted: Thu Oct 21, 2004 5:31 pm Post subject: Re: enable_if and operator[] (or workaround) |
|
|
"Michael Fawcett" <spam_mikef (AT) intelgames (DOT) com> wrote
| Quote: | The following is producing a compiler error with MSVS 7.1 :
template <typename X, typename Y = X, typename Z = Y
struct vec3
{
// operator[] will only be enabled if the typex == typey == typez
inline typename boost::enable_if
boost::is_same<Y, Z> >, X &>::type operator[](size_t idx);
inline typename boost::enable_if<boost::mpl::and_
boost::is_same<Y, Z> >, X const &>::type operator[](size_t idx) const;
};
int main(void)
{
vec3<float, int> a;
}
vec3_class.h(50): error C2039: 'type' : is not a member of
'boost::enable_if<Cond,T>'
with
[
Cond=boost::mpl::and_<boost::is_same,
T=float &
]
which would suggest that the compiler is doing more than just a syntax check
of the declaration. It's been a while since I've used enable_if, but isn't
this legal usage? Shouldn't I only get a compiler error if I attempt to use
operator[] with a class where X != Y or Y != Z?
|
The problem is that those operator[] *declarations* are instantiated
with the class. SFINAE only works on functions that are templated.
Non-templated member functions' definitions are instantiated only on
demand, but at the point the class is instantiated the types are all
determined, so type errors in the signatures of the functions count.
| Quote: | Apologies if this should have gone to the boost mailing list.
|
It should have. Why don't you post there?
HTH,
Dave
--
David Abrahams
Boost Consulting
http://www.boost-consulting.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Michael Fawcett Guest
|
Posted: Fri Oct 22, 2004 5:18 pm Post subject: Re: enable_if and operator[] (or workaround) |
|
|
"Peter Dimov" <pdimov (AT) gmail (DOT) com> wrote
| Quote: | "Michael Fawcett" <spam_mikef (AT) intelgames (DOT) com> wrote in message
news:<cl1isj$50u$1 (AT) gateway (DOT) northropgrumman.com>...
The following is producing a compiler error with MSVS 7.1 :
code snipped
which would suggest that the compiler is doing more than just a syntax
check
of the declaration. It's been a while since I've used enable_if, but
isn't
this legal usage?
No, it's not. enable_if/SFINAE only works with function templates.
Your operator[] functions are ordinary member functions. They are
members of a class template, but this doesn't turn them into function
templates, and their declarations are instantiated when the definition
of their enclosing class template is instantiated. Their _definitions_
will only be instantiated upon first use, though, so you can put a
static assert inside.
HTH.
|
Yes of course, thank you. I actually just read a section of "C++ Templates"
that told me exactly what you have suggested.
-Michael Fawcett
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kwikius Guest
|
Posted: Mon Oct 25, 2004 1:44 pm Post subject: Re: enable_if and operator[] (or workaround) |
|
|
"Michael Fawcett" <spam_mikef (AT) intelgames (DOT) com> wrote
| Quote: | The following is producing a compiler error with MSVS 7.1 :
template <typename X, typename Y = X, typename Z = Y
struct vec3
{
// operator[] will only be enabled if the typex == typey == typez
inline typename
boost::enable_if
boost::is_same<Y, Z> >, X &>::type operator[](size_t idx);
inline typename
boost::enable_if<boost::mpl::and_
boost::is_same<Y, Z> >, X const &>::type operator[](size_t idx) const;
};
int main(void)
{
vec3<float, int> a;
}
|
BTW assume should be eg vec3<float, float> a; above
Of course the problem is not insurmountable:
template <typename X, typename Y = X, typename Z = Y>
struct vec3
{
// operator[] will only be enabled if the typex == typey == typez
template <typename IDX>
inline
typename boost::enable_if<
boost::mpl::and_<
boost::is_same
boost::is_same<Y, Z>,
boost::is_convertible<IDX,size_t>
| Quote: | ,
X &
::type operator[](IDX idx);
|
template <typename IDX>
inline
typename boost::enable_if<
boost::mpl::and_<
boost::is_same
boost::is_same<Y, Z>,
boost::is_convertible<IDX,size_t>
| Quote: | ,
X const &
::type operator[](IDX idx)const;
|
};
should work ok
regards
Andy Little
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|