c++ template challenge

Started by
13 comments, last by Codeka 14 years, 6 months ago
So you want to reduce the number of function calls because they might be to much of an overhead, and you want to do this by creating and destroying instances of classes? This has to be a joke.

The construction and destruction of that instance take a function call each.
Someone who uses a, euhm..., delta!?
Advertisement
Quote:Original post by Makaan
Hello,

What you want to do is impossible.

It is by no means impossible.

But any solution will likely be fiddly and convoluted.

Quote:Original post by delta user
So you want to reduce the number of function calls because they might be to much of an overhead, and you want to do this by creating and destroying instances of classes? This has to be a joke.

It only takes a little imagination:

class SomeType{// ...};std::ostream &operator<< (std::ostream &out, const SomeType &x){    serializer s;    s.write(x);    return out << s.to_string();}


If the creation of a serializer and calls to the to_string() method are expensive, then having the ability spread the cost across the "streaming" of multiple objects is desirable.

But whether one should hide this inside convoluted code is debatable.
If you're worried about performance why not doing something like the queue?

TaskQueue q;q.Add(1);q.Add(2);q.Add(3);TaskExecuter e;e.ExecuteQueue(q);


Wouldn't that be much better? Add them once to a queue and do something with the values all at once?

Edit: sorry, didn't read the whole thing about function overhead. Okay, then why not something like this:

void Execute(int* array[], unsigned int nElements){    for (unsigned int i = 0; i < nElements; i++) {        //do something with (*array)    }}int main(){    int array[] = { 1, 2, 3, 4, 5, 6 };    const unsigned int nNum = sizeof(array) / sizeof(array[0]);    Execute(&array, nNum);}
What you're asking for sounds like an incredibly bad idea, but maybe something like this:

// The type that will receive arguments in the magical way.class Foo {  template <typename T, typename U>  void Exec(const T&, const U&);  template <typename T>  void Exec(const T&);};template <typename T>class odd_argument_binder_for_Foo {  public:  odd_argument_binder_for_Foo(Foo* foo, T* t): foo(foo), t(t), used(false) {}    // Only if something's left over at the end of a line.  ~odd_argument_binder_for_Foo() {    if (!used) { foo->Exec(*t); }  }  template <typename U>  friend Foo& operator<<(const odd_argument_binder_for_Foo& binder, const U& u);  private:  Foo* foo;  T* t;  // An operator<< chain will create multiple instances of the binder, all but  // one of which will be used to call the 2-argument form, and which should  // therefore not call the 1-argument form in the destructor. We use this  // flag to keep track.  bool used;  // Not copyable! Otherwise all kinds of hell could break loose.  odd_argument_binder_for_Foo(const odd_argument_binder_for_Foo&);  odd_argument_binder_for_Foo& operator=(const odd_argument_binder_for_Foo&);};// And now the magic.template <typename T>odd_argument_binder_for_Foo operator<<(const Foo& foo, const T& t) {  return odd_argument_binder_for_Foo(&foo, &t);}template <typename U>Foo& operator<<(const odd_argument_binder_for_Foo& binder, const U& u) {  binder.used = true;  Foo& foo = *(binder.foo);  foo.Exec(*(binder.t), u);  return foo;}
I thought about Zahlman's solution, but then I also thought about his "incredibly bad idea" disclaimer and stopped right there...

One of C++'s benefits is that it's always pretty clear what's going on under the hood. By intentionally obfuscating what's going on under the hood, you're just making your own life (and anybody who reads you code as well) much harder than it should be. If you want to reduce the number of function calls, then why don't you just reduce the number of function calls?

This topic is closed to new replies.

Advertisement