我打算在即将开始的项目中使用shared_ptr
,所以(不了解std::make_shared
)我想把一个可变参数模板函数spnew<T>(...)
写成{{1} } - 返回shared_ptr
的替身。一切顺利,直到我试图使用其构造函数包含new
的类型。当我尝试编译下面的最小例子时,我从GCC 4.5.2得到以下内容:
In function 'int main(int, char**)': too many arguments to function 'std::shared_ptr spnew(Args ...) [with T = Example, Args = {}]' In function 'std::shared_ptr spnew(Args ...) [with T = Example, Args = {}]': no matching function for call to 'Example::Example()'
奇怪的是,如果我用initializer_list
代替std::make_shared
,我会得到相同的错误。在任何一种情况下,当涉及spnew
时,似乎错误地推断出参数,错误地将initializer_list
视为空。这是一个例子:
Args...
这只是我的疏忽,还是一个错误?
答案 0 :(得分:1)
你可以这样做 -
#include <memory>
#include <string>
#include <iostream>
#include <vector>
struct Example {
template<class... Args>
Example(const char* t, Args... tail) : title(t)
{
Build(tail...);
}
template<class T, class... Args>
void Build(T head, Args... tail)
{
contents.push_back(std::string(head));
Build(tail...);
}
template<class T>
void Build(T head)
{
contents.push_back(std::string(head));
}
void Build() {}
std::string title;
std::vector<std::string> contents;
};
template<class T, class... Args>
std::shared_ptr<T> spnew(Args... args) {
return std::shared_ptr<T>(new T(args...));
}
int main(int argc, char** argv) {
auto succeeds = spnew<Example>("foo", "bar");
auto fails = spnew<Example>("foo", "bar", "poo", "doo");
std::cout << "succeeds->contents contains..." << std::endl;
for ( auto s : succeeds->contents ) std::cout << s << std::endl;
std::cout << std::endl << "fails->contents contains..." << std::endl;
for ( auto s : fails->contents ) std::cout << s << std::endl;
}
尽管通用模板是类型安全的,但编译器会抱怨它
如果传递的类型无法转换为contents.push_back
,则const char *
。
如上所述,您的代码在使用gcc 4.6时工作正常,但是此处会解释您收到的警告 why-doesnt-my-template-accept-an-initializer-list,可能不是标准 兼容,虽然c ++ 0x标准尚未发布,所以这可能会改变。
答案 1 :(得分:0)
使用gcc-4.7(可能也适用于gcc-4.6,只是分支)并带有警告:
foo.cpp: In function ‘int main(int, char**)’:
foo.cpp:29:47: warning: deducing ‘Args ...’ as ‘std::initializer_list<const
char*>’ [enabled by default]
foo.cpp:22:20: warning: in call to ‘std::shared_ptr<_Tp1> spnew(Args ...)
[with T = Example, Args = {const char*, std::initializer_list<const
char*>}]’ [enabled by default]
foo.cpp:29:47: warning: (you can disable this with -fno-deduce-init-list)
[enabled by default]
我不确定为什么有人会想要对init-list演绎加以补充。
有一个相关的主题: Why doesn't my template accept an initializer list
基本上,裸init-list没有类型。