For C++11 not really an issue anymore with the move semantics.
[I've updated my answer before you posted this message], so not "Big", but "Expensive".
If you pass std::string by value to a function, there will be "new" + copy. Move will not work here.
If you pass ComPtr<> by value, there will be AddRef/Release().
Does a pointer to reference conversion would ever make sense for you?
Nothing comes to my mind right now.
Let's take a look at the problem from a different angle:
Input:
1. You have COM object (by D3D), for example, texture.
2. You have wrapper - WRL::ComPtr<>, that stores a pointer (you can't do better with your code, because you need to store a pointer).
3. Reference counting is baked inside the texture, and not inside the wrapper (ComPtr).
std::shared_ptr<> will add 2 counters: ref + weak_ref.
4. COM is a C API (dll-bounary restriction)
5. Amount of D3D object usage inside a renderer is 1.000-50.000 (take a look by Alt+F5 in VS with your program).
Output:
1. What is it possible to improve here on CPU side?
2. Does it worth to improve it?