模板化一个 shared_ptr 参数

10

我在这段代码中遇到了编译错误:

#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>

struct Name
{
};
typedef boost::shared_ptr<Name> NamePtr;

struct Foo
{
    NamePtr name;
};
typedef boost::shared_ptr<Foo> FooPtr;

template<class T>
void setName(T item, NamePtr name = boost::make_shared<Name>() )
{
    item->name = name;  
}

int main()
{
    FooPtr foo = boost::make_shared<Foo>();
    setName(foo);
    return 0;
}

as follows:

    main.cpp: error C2780: 'boost::shared_ptr<X> boost::make_shared(A1 &&,A2 &&,A3 &&,A4 &&,A5 &&,A6 &&,A7 &&,A8 &&,A9 &&)' : expects 9 arguments - 0 provided
1>          c:\users\ebargri\desktop\boost_1_49_0\boost\smart_ptr\make_shared.hpp(590) : see declaration of 'boost::make_shared'
1>main.cpp: error C2780: 'boost::shared_ptr<X> boost::make_shared(A1 &&,A2 &&,A3 &&,A4 &&,A5 &&,A6 &&,A7 &&,A8 &&)' : expects 8 arguments - 0 provided
1>          c:\users\ebargri\desktop\boost_1_49_0\boost\smart_ptr\make_shared.hpp(534) : see declaration of 'boost::make_shared'
1>main.cpp: error C2780: 'boost::shared_ptr<X> boost::make_shared(A1 &&,A2 &&,A3 &&,A4 &&,A5 &&,A6 &&,A7 &&)' : expects 7 arguments - 0 provided
1>          c:\users\ebargri\desktop\boost_1_49_0\boost\smart_ptr\make_shared.hpp(480) : see declaration of 'boost::make_shared'
1>main.cpp: error C2780: 'boost::shared_ptr<X> boost::make_shared(A1 &&,A2 &&,A3 &&,A4 &&,A5 &&,A6 &&)' : expects 6 arguments - 0 provided
1>          c:\users\ebargri\desktop\boost_1_49_0\boost\smart_ptr\make_shared.hpp(428) : see declaration of 'boost::make_shared'
1>main.cpp: error C2780: 'boost::shared_ptr<X> boost::make_shared(A1 &&,A2 &&,A3 &&,A4 &&,A5 &&)' : expects 5 arguments - 0 provided
1>          c:\users\ebargri\desktop\boost_1_49_0\boost\smart_ptr\make_shared.hpp(378) : see declaration of 'boost::make_shared'
1>main.cpp: error C2780: 'boost::shared_ptr<X> boost::make_shared(A1 &&,A2 &&,A3 &&,A4 &&)' : expects 4 arguments - 0 provided
1>          c:\users\ebargri\desktop\boost_1_49_0\boost\smart_ptr\make_shared.hpp(330) : see declaration of 'boost::make_shared'
1>main.cpp: error C2780: 'boost::shared_ptr<X> boost::make_shared(A1 &&,A2 &&,A3 &&)' : expects 3 arguments - 0 provided
1>          c:\users\ebargri\desktop\boost_1_49_0\boost\smart_ptr\make_shared.hpp(284) : see declaration of 'boost::make_shared'
1>main.cpp: error C2780: 'boost::shared_ptr<X> boost::make_shared(A1 &&,A2 &&)' : expects 2 arguments - 0 provided
1>          c:\users\ebargri\desktop\boost_1_49_0\boost\smart_ptr\make_shared.hpp(240) : see declaration of 'boost::make_shared'
1>main.cpp: error C2780: 'boost::shared_ptr<X> boost::make_shared(A1 &&)' : expects 1 arguments - 0 provided
1>          c:\users\ebargri\desktop\boost_1_49_0\boost\smart_ptr\make_shared.hpp(198) : see declaration of 'boost::make_shared'
1>main.cpp: error C2783: 'boost::shared_ptr<X> boost::make_shared(void)' : could not deduce template argument for 'T'
1>          c:\users\ebargri\desktop\boost_1_49_0\boost\smart_ptr\make_shared.hpp(121) : see declaration of 'boost::make_shared'

我做错了什么?

如果我用以下代码替换模板函数,代码可以编译通过:

void setName(FooPtr item, NamePtr name = boost::make_shared<Name>())
{
    item->name = name;  
}

如果我用下面的代码替换它,它也会编译通过:
template<class T>
void setName(T item)
{
}

如果我将第二个参数设置如下,它也会编译:

FooPtr foo = boost::make_shared<Foo>();
NamePtr name = boost::make_shared<Name>();
setName(foo, name);

这也无法编译:
setName<FooPtr>(foo);

更新:

这里有另一个例子:

#include <boost/shared_ptr.hpp> 
#include <boost/make_shared.hpp> 

template<class T> 
void f(T item, boost::shared_ptr<int> name = boost::make_shared<int>()) 
{ 
} 

int main() 
{ 
    f(0); 
}

@stijn 结构体是具有默认公共构造函数的类。 - Baz
你是对的,刚刚使用std而不是boost进行了测试,有趣的是MSVC告诉我“make_shared' : 不是 'global namespace''_的成员。 - stijn
使用 setName(foo) 替换为 setName<FooPtr>(foo) 是否可行(应该是可以的,因为它实际上与具有 FooPtr 参数的非模板函数相同)?似乎编译器无法推断某些类型。 - Artem Sobolev
这个对我编译通过了,你用的是哪个编译器? - Salgar
在MSVC10中以更为简单的形式重现:#include <boost/shared_ptr.hpp> #include <boost/make_shared.hpp>template<class T> void f(T item, boost::shared_ptr<int> name = boost::make_shared<int>()) { }int main() { f(0); } - Igor R.
显示剩余6条评论
1个回答

4
这是一个VS的bug。示例:
namespace foo {
  template <typename T> class A {};
  template<typename T> A<T> mk_A() { return A<T>(); } 
}

template<class T> 
void f(T item, foo::A<int> x = foo::mk_A<int>()) { } // triggers the bug

using foo::mk_A;
template<class T> 
void g(T item, foo::A<int> x = mk_A<int>()) { } // does not trigger the bug


int main () {
  f(0); g(0);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接