Why do i have to type "test_c<int, void(int)>" instead of just "test_c<int>"

It works for test_f due to "template argument deduction". This applies only to template functions, not to template classes.

How to make this compile. What am i missing / doing wrong.

Don't use void(int). That simply means a function that takes an int and returns nothing. normal_struct_func is not a function, it's an object that has a () operator aka function object, functor etc. You could use std::function (make sure you include <functional>):

stuff like that.I know of unique_ptr but i wanted to create a single template class that could do all of the above.

The class was all good with pointers and arrays but when i tried to make it do stuff like example 1 i hit a brick wall because i want it to work with all functor, see "test_f tests" for example.

It seems to be very tricky to get it to work.One of the things i would like to minimize is the amount of typing required but the "template argument deduction" not for template classes rule, is in the way of that. auto keyword does n't help either.

It worked in the case of the func argument because you never use the default value in your tests. As soon as you write something like scoped<int, decltype(f)> f23(23); you'll get the same error.

Anyway, it still won't work. Once you fix this you'll get another error: '`anonymous-namespace'::<lambda1>::(const `anonymous-namespace'::<lambda1> &)' : cannot convert parameter 1 from 'default_empty<T>' to 'const `anonymous-namespace'::<lambda1> &'

Again, you're mixing up things that look like functions but they have different types. In the particular case that triggered the above error your deleter is a lambda and the default_empty is a function object. They're not compatible.

Let's take the case of make_scoped(new int(1975), normal_struct_fp()). This creates a scoped<int, normal_struct_fp> where m_onLeaveScope_empty is of type normal_struct_fp. And the scoped constructor is trying to assign an object of type default_empty<int> to a variable of type normal_struct_fp. That won't work, just because 2 types have an () operator with the same signature it doesn't mean that you can convert from one type to another.

How would i make it work or is that not a possibility without std::function?

Well, it seems to me that the only purpose of m_onLeaveScope_empty is to support the move constructor. You could leave the old m_onLeaveScope alone and add a null check in the scoped destructor so the old m_onLeaveScope doesn't get called.

Well, it seems to me that the only purpose of m_onLeaveScope_empty is to support the move constructor. You could leave the old m_onLeaveScope alone and add a null check in the scoped destructor so the old m_onLeaveScope doesn't get called.

Yes, I've thought of that, it would work for the pointer version, but not for the non pointer version.

We can't really test for m_obj != 0 since 0 might be a totally valid value.

The possible solution would be to add a bool that gets set to true (is_empty = true) when the data is moved.

This, i'm guessing, would also be faster then calling an empty function.

But i'm not sure which way to go. I want it to be correct and as performance as possible so i'm still wondering if there is some kind of template magic to sole this.

But i'm leaning to the bool solution or perhaps i should use std::function...

Performance wise I'd say that the bool variant is the fastest. std::function is cleaner but it has larger time & space overhead. But you know what they say, premature optimization is the root of all evil. Things like CreateFile or LoadLibrary will take far more time to complete than the few instructions that are need by make_scope/scoped.

If you really want it to be fast then the first thing you'll want to do is to get rid of make_scoped, it's not "free".

]]>http://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/1913bb8a1d3242a2aa3a9e940127a594#1913bb8a1d3242a2aa3a9e940127a594
Thu, 24 Feb 2011 17:56:25 GMThttp://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/1913bb8a1d3242a2aa3a9e940127a594#1913bb8a1d3242a2aa3a9e940127a594Dexter34http://channel9.msdn.com/Niners/Dexter/Discussions/RSSTech Off - C++0x (vs2010) question, please tell me what i'm doing wrongInteresting topic.But the code examples above will generate a lot of overhead for the small tasks it seems to be for. For example using it as a scoped_array.Best would be if you could make the optimizer inline , etc..Make the compiler do the heavy work for us.

I don't understand... that's exactly what the compiler did. The code in main is the code from normal_function, 3 calls to the stream insertion operator and nothing else.

]]>http://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/d701fa097b8c4289b5519f2c0059162a#d701fa097b8c4289b5519f2c0059162a
Tue, 26 Jul 2011 05:24:21 GMThttp://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/d701fa097b8c4289b5519f2c0059162a#d701fa097b8c4289b5519f2c0059162aDexter34http://channel9.msdn.com/Niners/Dexter/Discussions/RSSTech Off - C++0x (vs2010) question, please tell me what i'm doing wrong@Dexter: The code in my post was just an example of compiler optimization. How a good template class should work.

Both your code and Burkholder's code have a big overhead.Is there a way to minimize the overhead like in my example ?

]]>http://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/b17d6d3c8717452a9ee99f2c00ed7f0a#b17d6d3c8717452a9ee99f2c00ed7f0a
Tue, 26 Jul 2011 14:24:41 GMThttp://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/b17d6d3c8717452a9ee99f2c00ed7f0a#b17d6d3c8717452a9ee99f2c00ed7f0aJonas_No34http://channel9.msdn.com/Niners/Jonas_No/Discussions/RSSTech Off - C++0x (vs2010) question, please tell me what i'm doing wrongOK, I understand now. I don't know of a way to remove this overhead, std::function is horrible complex and the compiler has little chance to optimize it.

It seems to me that if you don't provide the function type in the template argument list (like in the original code or in your code) then the only alternative is to use std::function or something that does something similar: wraps a callable object. And this wrapping is complex because there are different types of callable objects: pointer to function, pointer to member, functors.

is_convertible and decay seens what you are looking for deal with functors, function and lambdas. There are other interesting stuff on the blog. (I think I see an example with std::bind for additional "magic"call somewhere, I'll try re-digg it)

]]>http://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/3d16e1be4afb42f7ac979f2e01229720#3d16e1be4afb42f7ac979f2e01229720
Thu, 28 Jul 2011 17:38:00 GMThttp://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/3d16e1be4afb42f7ac979f2e01229720#3d16e1be4afb42f7ac979f2e01229720new2STL34http://channel9.msdn.com/Niners/new2STL/Discussions/RSSTech Off - C++0x (vs2010) question, please tell me what i'm doing wrongHere's how STL would do it:http://channel9.msdn.com/Shows/Going+Deep/C9-Lectures-Stephan-T-Lavavej-Advanced-STL-6-of-n#c634477472460000000]]>http://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/dcb8826e776e422db9229f3300dc3489#dcb8826e776e422db9229f3300dc3489
Tue, 02 Aug 2011 13:21:44 GMThttp://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/dcb8826e776e422db9229f3300dc3489#dcb8826e776e422db9229f3300dc3489Jonas_No34http://channel9.msdn.com/Niners/Jonas_No/Discussions/RSSTech Off - C++0x (vs2010) question, please tell me what i'm doing wrongSTL's ScopeWarden class looks promising.I'm a bit disappointed that c++ is limited in the area of functor and lambda storing.I wonder why they have not done anything about it.Is it not common enough or do people just bite the bullet and take the dynamic allocation overhead and hope the cpu's get faster next year ?

]]>http://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/23207486318545099b409f370014775c#23207486318545099b409f370014775c
Sat, 06 Aug 2011 01:14:30 GMThttp://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/23207486318545099b409f370014775c#23207486318545099b409f370014775cMr Crash34http://channel9.msdn.com/Niners/Mr Crash/Discussions/RSSTech Off - C++0x (vs2010) question, please tell me what i'm doing wrong> Limited as in not being able to store functors and lambdas without overhead or workaround

std::function encapsulates that machinery. It inherently has nonzero cost, and inherently must throw exceptions for arbitrarily large functors.

There is no flaw to solve here.

]]>http://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/1ac46330fbd8478f8d5a9f3800100149#1ac46330fbd8478f8d5a9f3800100149
Sun, 07 Aug 2011 00:58:16 GMThttp://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/1ac46330fbd8478f8d5a9f3800100149#1ac46330fbd8478f8d5a9f3800100149STL34http://channel9.msdn.com/Niners/STL/Discussions/RSSTech Off - C++0x (vs2010) question, please tell me what i'm doing wrong@STL: std:function still have overhead which makes it less usable for doing small things. Like using in a scope guard class or special callbacks, etc..

Take this code and compile it in release mode / win32 and look at it in debugging.

function 'test_template' is a clear winner. Now the sad part is that you can't do this in a class without overhead because you have to store the function object which isn't really supported so you have to resort to tricks which have overhead.

This makes the scope_guard non-copyable but movable, so it can be returned by value without triggering the action of desctructor more than once. This allows the create_scope_guard function to do the template parameter deduction for you.

Use as:

auto guard = create_scope_guard([]() { cout << "foo" << endl; });

It's not entirely your syntax, but it's not too bad, I think.

It's essentially like STL's class but using a move constructor and a function in place of the macro.

Note that due to the behavior of copy elision in VC++ the move constructor isn't strictly necessary. VC++ lets you return a non-copyable object by value if it can perform copy elision. By contrast, g++ will not allow you to return an object by value without a public copy or move constructor, even if neither would be called due to copy elision.

I remember doing something similar. The problem was the same as in your suggestion.

It doesn't work for plain functions, in your case it because of "std::addressof".

I remember trying to use some template magic, traits, is_function<..>, conditional, enable_if, to make the compiler choose between two version but i failed miserably.

The compiler just didn't want to play ball. Either it's due to bugs in the compiler or me missing some small detail.

I just could figure out why it didn't work. Not even g++'s more helpful error messages helped me.

About 'Mr Crash' auto in class pseudo code: Would have been sweet if auto worked in classes like that. It would have reduced the pain of some template programming though it would surely cause other problems.

]]>http://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/7f4f60a5fe6f4c5c864c9f390111d4d5#7f4f60a5fe6f4c5c864c9f390111d4d5
Mon, 08 Aug 2011 16:36:59 GMThttp://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/7f4f60a5fe6f4c5c864c9f390111d4d5#7f4f60a5fe6f4c5c864c9f390111d4d5Jonas_No34http://channel9.msdn.com/Niners/Jonas_No/Discussions/RSSTech Off - C++0x (vs2010) question, please tell me what i'm doing wrongOkay, I've been doing some reading of N3242, and what VC++ is doing is wrong. The version of the class I presented should not work.

Both my version and STL's version are initialized using a non-const reference, which should not be able to bind to an rvalue. According to N3242, the result of a lambda expression is a pure rvalue, so you should not be able to call that constructor (or the create_scope_guard) using a lambda. STL's macro gets around that by storing the lambda in a local variable first, so he's not passing an rvalue to the function.

And come to think of it, using "create_scope_guard(noarg_functor());" shouldn't work either, because a temporary shouldn't bind to an non-const reference either. What's worse, I'm storing the address of that temporary, which is destructed as soon as create_scope_guard returns, so when the scope_guard goes out of scope it will try to use an already destructed object! Again, this doesn't apply to STL's version because if you use the macro, you're never passing a functor to it.

I find it very peculiar that VC++ lets you bind rvalue temporaries to non-const references, even though the standard explicitly forbids that, even in C++03.

Despite circumventing this issue (as long as you use the macro), STL's ScopeWarden class still won't work in g++ of course, due to the use of std::addressof (not yet supported) and __declspec(nothrow) (not standard).

Therefore, I believe the only way to make this safe to use on function pointers, functors and lambdas is to copy the function object by value. Yes, this may be problematic if the functor is large or has a non-trivial copy ctor, but I don't think there's another safe, standards-compliant way to do this.

]]>http://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/542ed78d4de6416783599f3a004f0e3c#542ed78d4de6416783599f3a004f0e3c
Tue, 09 Aug 2011 04:47:49 GMThttp://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/542ed78d4de6416783599f3a004f0e3c#542ed78d4de6416783599f3a004f0e3cSven Groot34http://channel9.msdn.com/Niners/Sven Groot/Discussions/RSSTech Off - C++0x (vs2010) question, please tell me what i'm doing wrong> STL's macro gets around that by storing the lambda in a local variable first, so he's not passing an rvalue to the function.

Yep, ScopeWarden is designed to invoke named functors (including named lambdas). The macro is just for convenience.

Because ScopeWarden is templated on functor type, it's physically impossible to give it an unnamed lambda.

Finally, observe that "explicit ScopeWarden(F&&);" is private and unimplemented. That prevents you, at compile-time, from constructing ScopeWarden<F> from an F rvalue.

(I am *very* careful.)

> I find it very peculiar that VC++ lets you bind rvalue temporaries to non-const references, even though the standard explicitly forbids that, even in C++03.

This is what I refer to as the Evil Extension. Always compile with /W4, which usually warns about any attempt to invoke the Evil Extension.

> Despite circumventing this issue (as long as you use the macro), STL's ScopeWarden> class still won't work in g++ of course, due to the use of> std::addressof (not yet supported)

Just say "&f". std::addressof() was for pedantic correctness, if someone has a functor that also overloads the address-of operator.

> and __declspec(nothrow) (not standard).

Just eliminate it - it's an optimization hint - or replace it with noexcept (GCC 4.6+). With noexcept, you don't need the try-catch-terminate in the dtor.

ScopeWarden is perfectly portable, I just didn't bother to write the minor ifdefs to make it so.

By the way - the problem with copying by value is that copy ctors can throw exceptions (what if the functor contains a std::string?). Consider what happens if you write:

do_X();

[... scope guard g to undo X, whose construction can throw ...]

do_Y();

g.dismiss();

If g's construction (or anything involved in it, like a helper function) throws, then X will remain done without Y being done. That violates transaction semantics, and defeats the whole purpose of a scope guard.

]]>http://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/ea6f4af7f1d54461b70a9f3b001932a9#ea6f4af7f1d54461b70a9f3b001932a9
Wed, 10 Aug 2011 01:31:44 GMThttp://channel9.msdn.com/Forums/TechOff/C0x-vs2010-question-please-tell-me-what-im-doing-wrong/ea6f4af7f1d54461b70a9f3b001932a9#ea6f4af7f1d54461b70a9f3b001932a9STL34http://channel9.msdn.com/Niners/STL/Discussions/RSSTech Off - C++0x (vs2010) question, please tell me what i'm doing wrongThe strange thing is, the existence of the private "explicit ScopeWarden(F&&);" prevents my template function creation approach from working with regular function pointers. If that declaration isn't there, it just uses the regular constructor, but if it is there, I get an error about not being able to access the private member.

By the way - the problem with copying by value is that copy ctors can throw exceptions

I realize that, but so can constructors. If I use your ScopeWarden like this:

SomeFunctor f;ScopeWarden<SomeFunctor> warden(f);

The constructor for f can still throw an exception, even if the ScopeWarden cannot. Is there any strong guarantee in the standard that construction of a lambda won't throw an exception?

Personally, if I were to use a class like this for transaction semantics, I'd probably use it like this:

SCOPE_WARDEN(if( isXDone ) UndoX(););DoX();

This circumvents the whole issue of throwing exceptions in the ctor.

This is similar to how C#'s using puts the variable outside the generated try/finally block, but its instantiation inside, and then in the finally block it checks for null before calling Dispose.

Ultimately the question here is: how would you define your ScopeWarden to be usablewithout a macro, but still require only a single statement to use and not require explicitly stating the template parameter? That's what I've been trying to do (more as a thought exercise rather than for anything practical), and what I think Jonas_No's goal was too.

Are you saying &func? That's an rvalue (observe that &(&func) would be bogus).

ScopeWarden could be partially specialized for function pointers (it's just obnoxious if you want to handle arbitrary calling conventions).

> The constructor for f can still throw an exception, even if the ScopeWarden cannot.

Yeah, ScopeWarden can't defend against that. "Don't do that then."

> Is there any strong guarantee in the standard that construction of a lambda won't throw an exception?

Lambdas with value captures of throwing types obviously can. The Standard appears to be silent about stateless lambdas, and lambdas with only value captures of non-throwing types (e.g. int) and reference captures, but no sane implementation will ever emit exceptions for those.

> Personally, if I were to use a class like this for transaction semantics, I'd probably use it like this:> SCOPE_WARDEN(if( isXDone ) UndoX();DoX();

Ah, but then X needs to record that it's done.

> This circumvents the whole issue of throwing exceptions in the ctor.

The SCOPE_WARDEN macro already avoids that.

> Ultimately the question here is: how would you define your ScopeWarden to be usablewithout> a macro, but still require only a single statement to use and not require explicitly> stating the template parameter? That's what I've been trying to do (more as a thought> exercise rather than for anything practical), and what I think Jonas_No's goal was too.

I don't think it can be done, and I thought about this for a long time while writing ScopeWarden.