Conditional function definition with boost::enable_if
Hi folks,
I would like to define a function in a class only if a child defines it.
In the below example, I would like the function f() to exist only in an
object bar if it defines a function i(). So far, my approach with
boost::enable_if failed because bar is not a complete type during
examination. T is clearly incomplete at the time when b is defined.
What would be the correct approach to solve this problem?
#include
Hi,
Would it be possible to derive from a class that has this function?
This way, the mother class is template, the template argument being
the child class (the curiously recursive template pattern). Then, in
the mother class, you can define f() and call i(). I don't know how
i() would be exactly called, but you get the idea.
Matthieu
2009/2/10 Matthias Vallentin
Hi folks,
I would like to define a function in a class only if a child defines it. In the below example, I would like the function f() to exist only in an object bar if it defines a function i(). So far, my approach with boost::enable_if failed because bar is not a complete type during examination. T is clearly incomplete at the time when b is defined. What would be the correct approach to solve this problem?
#include
#include template <typename T> struct foo { typename boost::enable_if< typename boost::is_function<typename T::i>::type, void
::type f() { } };
struct bar : foo<bar> { void i() { } };
int main() { bar b; b.f(); // should only compile since bar defines i()
return 0; }
enable_if.cc: In instantiation of 'foo<bar>': enable_if.cc:16: instantiated from here enable_if.cc:10: error: invalid use of undefined type 'struct bar' enable_if.cc:16: error: forward declaration of 'struct bar' enable_if.cc: In function 'int main()': enable_if.cc:25: error: 'struct bar' has no member named 'f'
Matthias -- Matthias Vallentin vallentin@icsi.berkeley.edu http://matthias.vallentin.cc _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Information System Engineer, Ph.D. Website: http://matthieu-brucher.developpez.com/ Blogs: http://matt.eifelle.com and http://blog.developpez.com/?blog=92 LinkedIn: http://www.linkedin.com/in/matthieubrucher
On Tue, Feb 10, 2009 at 09:34:20PM +0100, Matthieu Brucher wrote:
Would it be possible to derive from a class that has this function? This way, the mother class is template, the template argument being the child class (the curiously recursive template pattern). Then, in the mother class, you can define f() and call i(). I don't know how i() would be exactly called, but you get the idea.
Could you substantiate your solution with a short example, I think I don't understand which direction you're heading. What I'm trying to accomplish and express in code is the following idea: If you provide a function (i), you get functionality from the parent (f). Matthias -- Matthias Vallentin vallentin@icsi.berkeley.edu http://matthias.vallentin.cc
2009/2/10 Matthias Vallentin
On Tue, Feb 10, 2009 at 09:34:20PM +0100, Matthieu Brucher wrote:
Would it be possible to derive from a class that has this function? This way, the mother class is template, the template argument being the child class (the curiously recursive template pattern). Then, in the mother class, you can define f() and call i(). I don't know how i() would be exactly called, but you get the idea.
Could you substantiate your solution with a short example, I think I don't understand which direction you're heading. What I'm trying to accomplish and express in code is the following idea:
If you provide a function (i), you get functionality from the parent (f).
Matthias -- Matthias Vallentin vallentin@icsi.berkeley.edu http://matthias.vallentin.cc _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Something like (not the correct code though):
template<class Child>
struct MyfStruct
{
typename boost::enable_if
Hi Matthieu, On Wed, Feb 11, 2009 at 09:22:47AM +0100, Matthieu Brucher wrote:
template<class Child> struct MyfStruct { typename boost::enable_if
::type f() { // Do some stuff, but I don't know how to call i(), you will have to test :| } }; where has_i<> tests if the child has the method i().
Then, if you find how to call i() from the f() method, you just have to write:
class MyClass: public MyfStruct<MyClass> { void i(); // f() will be callable now };
Thanks for your example. Yet I believe, that the solution you propose does
not solve the underlying problem: as the compiler errors indicate,
struct bar (or in your example, class MyClass) is incomplete at the time
when has_i<Child> [*] is called. Hence, bar/MyClass cannot use CRTP to
automatically derive functions from foo/MyfStruct. I will have to use a
different approach to inject functions conditionally.
Matthias
[*] This would factor out the code that checks whether T has i():
template <typename T>
struct has_i
: boost::mpl::bool_
participants (2)
-
Matthias Vallentin
-
Matthieu Brucher