[SmartPtr] shared_ptr as a default value in function template
Hello,
In the wake of one of recent SO posts... The following doesn't compile
in MSVC10 (Boost 1.53):
#include
On 23.5.2013 13:08, Igor R wrote:
Hello,
In the wake of one of recent SO posts... The following doesn't compile in MSVC10 (Boost 1.53):
#include
#include template<class T> void f(T item, boost::shared_ptr<int> name =oost::make_shared<int>()) { }
int main() { f(0); }
Interesting.. but: It seems to be a MSVC related issue; Unless the templated function (make_shared in this case) is in the same namespace as the called templated function (f in this case) MSVC throws an error. Place both under the same namespace and the error disappears. Say using namespace and the problem disappears. Google revealed this: http://stackoverflow.com/questions/2788765/stdmake-shared-as-a-default-argum... Unfortunaly, the Microsoft Connect link is dead so I don't know if this was ever fixed. MSVC8 has this problem too (and it wasn't ever fixed for that version). Here's a small test case. Doesn't compile on MSVC8 but no problems whatsover with GCC 4.4.5. template < typename T > T same_ns() { return 42; } namespace foo { template < typename T > T diff_ns() { return 42; } } template < typename T > void f(int answer =ame_ns< int >()) {} // workaround using namespace foo; template < typename T > void u(int answer =iff_ns< int >()) {} // compiles template < typename T > void p(int answer =oo::diff_ns< int >()) {} // does not compile on msvc int main() { f< int >(); u< int >(); p< int >(); return 0; } -- Pekka
It seems to be a MSVC related issue; Unless the templated function (make_shared in this case) is in the same namespace as the called templated function (f in this case) MSVC throws an error.
Good finding, thanks!
Note however that the following does compile in MSVC:
#include
On 23.5.2013 16:40, Igor R wrote:
It seems to be a MSVC related issue; Unless the templated function (make_shared in this case) is in the same namespace as the called templated function (f in this case) MSVC throws an error.
Good finding, thanks!
Note however that the following does compile in MSVC:
#include
#include void f(int, boost::shared_ptr<int> = boost::make_shared<int>()) { } int main() { f(0); } So, it's still unclear in what cases exactly this bug occurs.
The bug occurs if both the default argument and the function that has the default argument are templated. There could be some other cases too, but either a) move everything under the same namespace scope, b) drop f() template, c) drop default argument template (eg. non-templated make_shared wrapper if the make_shared type does not relate to f()'s templated type T); Every option sucks, just pick your poison. So, template < typename T > void foo(T, arg_type arg = ns::templated< some_type >()) does not work, but void foo (arg_type arg = ns::templated< some_type >()) and template < typename T > void foo(T, arg_type arg = ns::not_templated()) work. Typical MSVC everyday bs... -- Pekka
On 5/23/2013 9:57 AM, Pekka Seppänen wrote:
On 23.5.2013 16:40, Igor R wrote:
It seems to be a MSVC related issue; Unless the templated function (make_shared in this case) is in the same namespace as the called templated function (f in this case) MSVC throws an error.
Good finding, thanks!
Note however that the following does compile in MSVC:
#include
#include void f(int, boost::shared_ptr<int> = boost::make_shared<int>()) { } int main() { f(0); } So, it's still unclear in what cases exactly this bug occurs.
The bug occurs if both the default argument and the function that has the default argument are templated. There could be some other cases too, but either a) move everything under the same namespace scope, b) drop f() template, c) drop default argument template (eg. non-templated make_shared wrapper if the make_shared type does not relate to f()'s templated type T); Every option sucks, just pick your poison.
So, template < typename T > void foo(T, arg_type arg = ns::templated< some_type >()) does not work, but void foo (arg_type arg = ns::templated< some_type >()) and template < typename T > void foo(T, arg_type arg = ns::not_templated()) work.
Typical MSVC everyday bs...
and the above code continues to faile to compile with MSVC11. Jeff
participants (3)
-
Igor R
-
Jeff Flinn
-
Pekka Seppänen