my compilers::tdm gcc4.5.2
my os::windows xp sp3(32bits)
boost 1.45

Sorry, I have another problem again

template<typename accStrategy = float>
int const adaptSR(int const MAX_AL, float const CONFIDENT_LV, int const OFFSET, accStrategy PLAN)
{
  return 1; 
}

template<typename accStrategy = float>
int const adaptSR(int const MAX_AL, float const CONFIDENT_LV, int const OFFSET)
{
  return 1;  
}

template<typename T>
void testArg(T haha)
{
  int const MAX_AL = 10;
  float const CONFIDENT_LV = 10;
  int const OFFSET = 10;
  haha(MAX_AL, CONFIDENT_LV, OFFSET);
}

void testBind()
{
  //boost::accumulators::accMeanStDv<float> accMSD;
  bindClass bc;
  float a = 3;
  testArg(boost::bind<int>(adaptSR<int>, _1, _2, _3) );
  testArg(boost::bind<int>(adaptSR<float>, _1, _2, _3, a) );
  testArg(boost::bind<int>(adaptSR<bindClass>, _1, _2, _3, bc ));
  testArg(boost::bind<int>(adaptSR<bindClass>, _1, _2, _3, boost::cref(bc) ));
}

error message

error: too few arguments to function

I don't know how to solve the overloaded problem like this one
looks like the compiler is able to catch the "first" function I declare only
It can't catch the second one
Thanks a lot

Recommended Answers

All 8 Replies

> my compilers::tdm gcc4.5.2

You have a current C++ compiler; prefer using std::bind over boost::bind (compile with -std=c++0x)

> I don't know how to solve the overloaded problem like this one

boost::bind or std::bind have no good way to figure out which overload you intended to bind. You have to disambiguate the overload yourself. For example:

#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <functional>

int foobar( int a, int b ) { return a+b ; }

double foobar( double a, double& b, double c ) { return b = a-b+c ; }

int main()was meant to be bound.
{
    // disabiguate the overloaded functions for boost::bind
    int (&int_foobar)(int,int) = foobar ;
    double (&dbl_foobar)(double,double&,double) = foobar ;

    boost::function< int(int) > f1 = boost::bind( int_foobar, _1, 23 ) ;
    std::cout << f1(99) << '\n' ;

    double b = 56.2 ;
    boost::function< double(double,double) > f2 = 
                                    boost::bind( dbl_foobar, _1, boost::ref(b), _2 ) ;
    std::cout << f2( 17.4, 23.9 ) << ' ' << b << '\n' ;

    // same disambiguation is also needed for C++0x std::bind
    std::function< int(int) > f3 = std::bind( int_foobar, std::placeholders::_1, 23 ) ;
    std::cout << f3(99) << '\n' ;

    b = 56.2 ;
    // but in C++0x using a lambda function instead is so much easier
    auto f4 = [&b] ( double a, double c ) { return foobar(a,b,c) ; } ;
    std::cout << f4( 17.4, 23.9 ) << ' ' << b <<  '\n' ;
}

Thanks, but when things mess up with template
It can't work as the way you show me
The most easiest way for me now is changing the name of the function

> when things mess up with template
> It can't work as the way you show me

You need to disambiguate the overload. As long as you do that, it would work - templates or no templates.

#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <functional>

template < typename T > T foobar( T a, T b ) { return a+b ; }

template < typename T > T foobar( T a, T& b, T c ) { return b = a-b+c ; }

int main()
{
    // disabiguate the overloaded functions for boost::bind
    int (&int_foobar)(int,int) = foobar ;
    double (&dbl_foobar)(double,double&,double) = foobar ;

    boost::function< int(int) > f1 = boost::bind( int_foobar, _1, 23 ) ;
    std::cout << f1(99) << '\n' ;

    double b = 56.2 ;
    boost::function< double(double,double) > f2 =
                        boost::bind( dbl_foobar, _1, boost::ref(b), _2 ) ;
    std::cout << f2( 17.4, 23.9 ) << ' ' << b << '\n' ;

    // same disambiguation is also needed for C++0x std::bind
    std::function< int(int) > f3 = std::bind( int_foobar, std::placeholders::_1, 23 ) ;
    std::cout << f3(99) << '\n' ;

    b = 56.2 ;
    // but in C++0x using a lambda function instead is so much easier
    auto f4 = [&b] ( const double a, const double c ) { return foobar(a,b,c) ; } ;
    std::cout << f4( 17.4, 23.9 ) << ' ' << b <<  '\n' ;
}

> The most easiest way for me now is changing the name of the function

Using lambda functions (with type deduction if needed) would be easier.

I think that the easiest way to do it is to simply use a functor with both overloads. Something like this for example:

struct adaptSR_type {
  typedef int result_type;

  template<typename accStrategy>
  int const operator()(int const MAX_AL, float const CONFIDENT_LV, int const OFFSET, accStrategy PLAN)
  {
    return 1; 
  }

  int const operator()(int const MAX_AL, float const CONFIDENT_LV, int const OFFSET)
  {
    return 1;  
  }
} adaptSR;

template<typename T>
void testArg(T haha)
{
  int const MAX_AL = 10;
  float const CONFIDENT_LV = 10;
  int const OFFSET = 10;
  haha(MAX_AL, CONFIDENT_LV, OFFSET);
}

int main()
{
  float a = 3;
  testArg(boost::bind(adaptSR, _1, _2, _3) );
  testArg(boost::bind(adaptSR, _1, _2, _3, a) );
}

Of course, your template overloads have to be callable without explicit template arguments, so you need to make sure they can be deduced from the parameter types. And if you need to use explicit template arguments, you can simply make the functor a class template. I think that solution makes it a lot nicer on the user-side code.

Thank you very much, I finally know how to solve this kind of problem

include<iostream>
include<boost/bind.hpp>
include<boost/function.hpp>
include<functional>

template<typename T> T foobar( T a, T b ) { return a + b ;}
template<typename T> T foobar( T a, T& b, T c ) { return b = a - b + c; }

int main()
{
  int(&int_foobar)(int, int) = foobar;  
  auto f1 = boost::bind(int_foobar, _1, 23); //this line is ok
  boost::function< int(int) > f2 = boost::bind( int_foobar, _1, 23 ) ;//this line would give me warning
  std::cout << f1(99) << '\n' ;
  testArg(f1(23));
}

But from the code above, I got some warning message like this
dereferencing type-punned pointer will break strict-aliasing rules

Should I care about the warning message?

Thank you

I use boost::bind rather than std::bind because I am afraid that the features
of c++0x haven't supported by many compilers yet
According to the advices of scott meyers, platform independent sometimes could be very important
although I don't need to port my code to different platform
and can't understand how important it could be, but I think I should just listen
to those c++ master before I have the ability to discern which one is wrong or
right if I am capable to follow their advices.
Besides, there are two things I want to ask too

How could I cooperate with c programmers without changing the interfaces?
like

void example(float*** datOne, float****datTwo)

and

void example(myList *datOne, myRBTree *datTwo)

Besides, there are std::tr1::bind and std::bind, std::tr1::ref and std::ref and lots of things like that
which namespace should I prefer, std::tr1 or std?
Thanks a lot

> dereferencing type-punned pointer will break strict-aliasing rules
> Should I care about the warning message?

If you get this warning in your own code, you should certainly care about it. This means that aliasing rules as specified in 3.10/15 of IS have been violated resulting in undefined behaviour. See http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html

In this particular case, you can safely ignore the warning; it arises because of a known bug resulting from the interaction of boost::bind/boost::function/g++ 4.5. This has been known for a while, and AFAIK, has been now fixed.
See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44164
and: https://svn.boost.org/trac/boost/ticket/4538

I would still think that writing this code with C++0x lambdas and type inference is easier:

#include <iostream>

template < typename T > T foobar( T a, T b ) { return a+b ; }

template < typename T > T foobar( T a, T& b, T c ) { return b = a-b+c ; }

template< typename FUNCTION, typename T >
auto call_it( FUNCTION f, T t ) -> decltype ( f(t) ) { return f(t) ; }

int main()
{
    auto fun = [] ( int a ) { return foobar(a,23) ; } ; // 23 is bound as arg 2
    std::cout << call_it( fun, 99 ) << '\n' ;
}

I agree that this would work only with newer compilers eg. g++ 4.5 or 4.6, microsoft VC++ 2010
boost::bind/boost::function would work on most older compilers too. C++0x is currently at FCD stage and would become the IS for C++ in some months time, and there would be nothing platform dependent about these then - all conforming compilers have to support it.

If the idea is to write production code that would run on a variety of old and new implementations, stick to boost::bind/boost::function.

I would like to use boost::multi_array to instead of something like float*** or float **** or even ******
And I would like to use std::map or the other associative containers to replace
different "myRBTree".
Do I have some easy ways to do this without copy and paste?My classmates
would ask me don't use stl, boost or template because they don't know what
I am writing about.
I could finish small projects or homeworks all by myself, but when the
projects become bigger and bigger, I think I would need to cooperate with
other's people. But most of the classmates of mine only know c and they
refuse to learn c++, so how could I cooperate with them?
If I could make the code independent from interface, I think the problem
could be solved(maybe?).But how to do that?Template?But they don't like template,
even with template they need to satisfy some constraints(concepts?)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.