EDIT
Just like to clear this answer!
I've read your question and the answer has to do with the security context that has been put in place for a reason.
When using the SPContext.Current.Web or any context appart from .OpenWeb() it is already using the current users security context(read, write,full permissions). Open web is creating a new SPWeb object as I've already stated!
Because it's running under the current user's security context, say I have an account that has read only access its regardless weather I've done runwithelevated priv it wouldn't work because the security is already set, unless as you noted you use usertoken! That being said the code is trying to update or add an item to a list or library but fails as the security context under the current user wouldn't allow to give me the permission to run under pool account or even admin account.
Having the open web is run under a new thread that needs to be disposed of as I've noted first time round as its creating a new object, anything with the "new" object needs to be disposed and can be elevated so doesn't have any security restrictions (security). this can also be interchangeable between SPWebs/SPSites respectively.
This is not the case with SPContext.Current.Web , the only exception is when using the SPUser object where it would run into a known bug and running with elevated priv would do nothing, you would need to create a new SPUser and add SPWeb.EnsureUser(user.LoginName); within the elevated security context for it to work.
So rule of thumb SPContext.Current(like SPContext.Current.Web) uses the current user's security context tied to it making a tighter security around your code.
But SPContext.Current.Site.OpenWeb() creates a new SPWeb object that doesn't have any security context tied to it, leaving you to change security context or elevate privs without restrictions!
Both open the same SPWeb or SPSite, the only difference is the security context tied to the current context of the user that you should not dispose of!
.........................
Just as a note:
There are a few key takeaways for SharePoint projects:
• Always dispose your SPWeb / SPSite objects --> memory leaks
• Make use of SPContext.Current... when you are sure your code is running in a SharePoint context
• Unit Tests mean no Sharepoint context
• External utilities mean no Sharepoint context
• Powershell means no SharePoint context (e.g. activating a feature with feature receiver might fail)
•Do not dispose SPContext.Current... but create your own object (again using) You might have problems with consistency with your multiple SP.. objects.
In the end SPSite site = SPContext.Current.Web.Site; is fine in some instances, but you do not have control over this site object - that might be the problem. If you go for new SPSite(...) you will always have your SPSite and not something SharePoint created and managed for you.
Personally I almost always go for the using structure so all objects are disposed properly afterwards. When I do quick and dirty solutions I use SPContext.Current.Web without disposing.
https://stackoverflow.com/questions/8052190/spsite-site-new-spsitespcontext-current-web-url-vs-spcontext-current-web-sit
Also as I've said:
What is the need of defining SPSite, SPWeb objects especially in RunWithElevatedPrivileges block? If you use instances of SPSite or SPWeb, obtained prior to the RunWithElevatedPrivileges block, it won't work as expected because they are already associated to a non-elevated security context [meaning current logger user]
Why can’t we use SPContext.Current.Web inside RunWithElevatedPrivileges: SPContext.Current.Web can not be used directly with in the RunWithElevatedPrivileges block as the SPWeb object becomes a instance of current logged-in user's context and it gives the below error if tries to update any content in the same Web with READ only access. Error : Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack. To address the issue, a new instance of SPSite and SPWeb should be created within theRunWithElevatedPrivileges code block as above.
in this case SPContext.Current.Site.OpenWeb() creates a new thread from the current context and is like creating a new spweb, this means more control but also means you need to dispose of the object.
http://sharepointquicksolutions.blogspot.in/2012/11/all-ways-of-runwithelevatedprivileges.html
So you can see the picture here! That there are less privileges to the CurrentContext that's using the same thread eg SPContext.Current.Web whereas SPContext.Current.Site.OpenWeb() is a new thread that doesn't have the restrictions in place due to the first one already being set and used whereas the second one is created by you and can be changed (security wise) means no restrictions on actions but also means you need to handle the disposing of the SPWeb object.