template<typename anyFunctor = printTxt> //printTxt is somekind of functor
void testFunctor()
{
  anyFunctor f;
}

void testFunctor2()
{
  testFunctor();  
}

1 : if type anyFunctor need 3 arguments to initialize it, what should I do?
Do I have another way to make this become more adaptable except
of passing strategies like parameter(the way of stl did)

2 : if type anyFunctor need to accept different number of variables, how could I make it adaptable?

template<typename anyFunctor = printTxt> //printTxt is somekind of functor
void testFunctor()
{
  anyFunctor f;
  int a = 10;
  f(a);//it could accept one parameter only by the default
  //what if i want to make it act like f(a, b)?
  //just like the way std::bind2nd or boost::bind did  
}

Do I need to pass it as arguments if I want to implement it by std::tr1::bind?
Thank you very much

>>Do I need to pass it as arguments if I want to implement it by std::tr1::bind?

If the AnyFunctor needs arguments when called, you need to get those arguments from somewhere. So the idea, like in your last piece of code, to create some temporary variable with some arbitrary value and passing them to the function is kind of ridiculous (unless this is a concept-check, in which case, there are far better ways to do this). So, yes, you will need to pass those parameters to the testFunctor() function and then forward them to the functor call.

1 : if type anyFunctor need 3 arguments to initialize it, what should I do?
Do I have another way to make this become more adaptable except
of passing strategies like parameter(the way of stl did)

The way STL does it is pretty much the only scalable way to do this. You can also use the Boost.Lambda constructor/destructor templates to bind the constructor call with some parameters, but I doubt it will help much.


2 : if type anyFunctor need to accept different number of variables, how could I make it adaptable?

Just like std::tr1::bind did it (or as I would refer to it as Boost.Bind). With C++0x, the coming standard, the support for variadic templates will allow you to do this in one shot:

template <typename anyFunctor, typename... Args>
void testFunctor(Args... args) {
  anyFunctor f;
  f(args...);
}; //all of this is actually, literally compilable with C++0x.

For now, just use boost::bind (or std::tr1) in some way. Because the alternative to the above use of variadic templates is to literally enumerate all the possible number of arguments, as such:

template <typename anyFunctor = printTxt>
void testFunctor() { anyFunctor f; f(); };

template <typename anyFunctor, typename Arg1>
void testFunctor(Arg1 a1) { anyFunctor f; f(a1); };

template <typename anyFunctor, typename Arg1, typename Arg2>
void testFunctor(Arg1 a1, Arg2 a2) { anyFunctor f; f(a1,a2); };

//... etc. for any number of arguments.

This is already done in the current implementation of boost::bind or std::tr1::bind, so I would recommend trying to reuse it if possible.

If you wanted to implement it by boost::bind, I would recommend you just pass the functor as a parameter, bound to the call parameters:

template <typename anyFunctor = printTxt>
void testFunctor(anyFunctor f = anyFunctor()) {
  f();
};

struct Foo {
  int value; 
  Foo(int aValue) : value(aValue) { };
  void operator()(int aOtherValue) { std::cout << (value + aOtherValue) << std::endl; };
};

struct Bar {
  void operator()() { std::cout << "Bar" << std::endl; };
};

int main() {
  testFunctor(boost::bind(Foo(42), 13)); //this will call Foo (initialized with 42) and called with number 13.
  testFunctor(); //this will call printTxt.
  testFunctor<Bar>(); //this will construct and call a Bar functor.
};

Edited 5 Years Ago by mike_2000_17: n/a

Comments
I learnt stuff, thanks

Thanks a lot, variadic templates looks cool
What is the cost about it(compile time, runtime or both)?
Thanks a lot

>>What is the cost about it(compile time, runtime or both)?

Compile-time: The usual costs of using templates (some code bloat, cannot be precompiled, some increase in compilation time just to resolve the appropriate template instantiations). But, variadic templates are, I imagine, easier for the compiler resolve than the equivalent template code from the current standard C++98.

Run-time: None. (at least, no more than the equivalent hard-coded, non-templated version)

Edited 5 Years Ago by mike_2000_17: n/a

I saw some use of template variadic with the recursive call
Are those recursive call also finish in compile times too?

Thank you

>>Are those recursive call also finish in compile times too?

You will find two types of recursive use of variadic templates:

Recursive Template Instantiations: This is when the template arguments are used to recursively instantiate templates of itself (with fewer arguments). For example, the tuple implementation:

template <typename Head, typename... Tail>
class tuple : private tuple<Tail...> {
  //...
};

These are unrolled at compile-time and become a single "normal" class.

Recursive Function Template Calls: This is the case for example, of the type-safe printf() function that uses variadic templates. It will call itself with fewer and fewer parameters until there is just the string parameter. These are calls will cause a recursive instantiation of all the "child" function templates. Afterwards, it is just like a collection of "normal" functions which are subject to the same optimization rules about inlining functions and unrolling recursive calls. It is fairly likely that simple functions with no state and that satisfy tail-recursion to be turned into just one function. Otherwise, it is just like any other recursion, they will cause stack a wind-up if the compiler cannot do anything about that. But, since these functions are likely to be single-serving, it is likely that the compiler will inline them.

>>they could be solve at compile times?

Well, it goes without saying that you have to turn on all the optimizations (-03), and hope for the best. Inspecting assembly listings (with option -S ) is the way to check it out (but you have to know assembly though..).


>>But according to the link at below, looks like this is not a common technique between those compiler vendors yet

Yes, of course, compilers don't support C++0x yet (it is not yet the standard after all). When it comes to early feature-full support, only GCC really matters. The other vendors are historically bad at keeping their compilers standard and feature-full. The only other exception is probably Comeau. I would guess that ICC won't take too long to comply either (especially for all the concurrent programming features). I would be surprised if the MSVC compiler gets to full compliance with C++0x by the time the next standard after that is coming out (circa 2016+), since only the 2010 version is of decent quality with respect to C++98.

I personally use GCC 4.6.0 experimental (that I compile from source on roughly a monthly basis), this guarantees as much C++0x support as possible and fast template meta-programming compilations. But otherwise, version 4.5.2 is pretty good too and is available on most platforms as binary distribution.

BTW, without variadic templates, you can still do the manual coding for each different number of arguments (up to maybe 10 or something like that). This is usually enough for most applications (that's how Boost implements some features that act as if they used variadic templates, for several libraries, notably Boost.Bind (which could be implemented in less than 20-30 lines of code with variadic templates, but turns out to be several hundred LOC long)).

Edited 5 Years Ago by mike_2000_17: n/a

>>(but you have to know assembly though..).
only learn some knowledge about assembly(8051)
To tell you the truth, it is very verbose and tire to work with assembly for me
Thank you very much

ps : I deeply hope that c++0x could become a formal standard in 2011

This question has already been answered. Start a new discussion instead.