将包含initializer_list的参数包扩展为构造函数

Jon*_*rdy 7 c++ variadic-functions initializer-list variadic-templates c++11

我打算shared_ptr在即将到来的项目中使用相当多的东西,所以(没有意识到std::make_shared)我想写一个可变参数模板函数spnew<T>(...)作为一个 - shared_ptr返回的替身new.一切顺利,直到我试图使用一个构造函数包含一个类型的类型initializer_list.当我尝试编译下面的最小示例时,我从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()'

奇怪的是,如果我代替我得到相当于错误std::make_sharedspnew.在任何一种情况下,当initializer_list涉及到时,似乎错误地推断出参数,错误地将其Args...视为空.这是一个例子:

#include <memory>
#include <string>
#include <vector>

struct Example {

    // This constructor plays nice.
    Example(const char* t, const char* c) :
        title(t), contents(1, c) {}

    // This one does not.
    Example(const char* t, std::initializer_list<const char*> c) :
        title(t), contents(c.begin(), c.end()) {}

    std::string title;
    std::vector<std::string> contents;

};

// This ought to be trivial.
template<class T, class... Args>
std::shared_ptr<T> spnew(Args... args) {
    return std::shared_ptr<T>(new T(args...));
}

// And here are the test cases, which don't interfere with one another.
int main(int argc, char** argv) {
    auto succeeds = spnew<Example>("foo", "bar");
    auto fails = spnew<Example>("foo", {"bar"});
}
Run Code Online (Sandbox Code Playgroud)

这只是我的疏忽,还是一个错误?

ems*_*msr 0

使用 gcc-4.7(可能也适用于 gcc-4.6,只是分支)并带有警告:

\n\n
foo.cpp: In function \xe2\x80\x98int main(int, char**)\xe2\x80\x99:\nfoo.cpp:29:47: warning: deducing \xe2\x80\x98Args ...\xe2\x80\x99 as \xe2\x80\x98std::initializer_list<const \nchar*>\xe2\x80\x99 [enabled by default]\nfoo.cpp:22:20: warning:   in call to \xe2\x80\x98std::shared_ptr<_Tp1> spnew(Args ...) \n[with T = Example, Args = {const char*, std::initializer_list<const \nchar*>}]\xe2\x80\x99 [enabled by default]\nfoo.cpp:29:47: warning:   (you can disable this with -fno-deduce-init-list) \n[enabled by default]\n
Run Code Online (Sandbox Code Playgroud)\n\n

我不确定为什么有人会想要抱怨初始化列表推导。

\n\n

有一个相关线程:\n为什么我的模板不接受初始值设定项列表

\n\n

基本上,裸露的初始化列表没有类型。

\n