C++ 带可变参数的模板函数编译问题

C++ 带可变参数的模板函数编译问题,c++,c++11,C++,C++11,我不熟悉带可变参数的模板函数。该代码受Codeview文章的启发,不在CreateBook()上编译,需要帮助 我想使用factory方法和模板创建一个对象 using namespace std; template<class T> class bar { public: template<class... Args> static bar<T> CreateBook(Args&&... args) {

我不熟悉带可变参数的模板函数。该代码受Codeview文章的启发,不在CreateBook()上编译,需要帮助

我想使用factory方法和模板创建一个对象

using namespace std;

template<class T>
class bar
{
public:
    template<class... Args>
    static bar<T> CreateBook(Args&&... args)
    {
        return bar<T>(std::forward<Args>(args)...); // Don't compile here
    }

    T get()
    {
        return val;
    }
private:

    bar(const T& t) :val(t) {}
    T val;

};

struct book
{
    string name;
    int phone;
    book(string s, int t) : name(s), phone(t) {}
};

void print(bar<book> k)
{
    cout << k.get().name << " " << k.get().phone << endl;
}

int main()
{
    bar<book> b = bar<book>::CreateBook("Hello World",91520);

    print(b);

    return 0;
}
使用名称空间std;
模板
分类栏
{
公众:
模板
静态条CreateBook(Args&&…Args)
{
返回栏(std::forward(args);//不要在这里编译
}
不明白
{
返回val;
}
私人:
bar(const T&T):val(T){
T值;
};
结构体的构造
{
字符串名;
国际电话;
图书(字符串s,int t):姓名(s),电话(t){}
};
空白打印(k栏)
{

看这段代码。你的bar构造函数也应该处理pack参数

template<class... X>
bar(X... x) :val(x...) {}
模板
bar(X…X):val(X…){

每一个问题都可以通过增加一层来解决

首先,让我们隔离Factory的作业。它应该只执行一项任务。
Factory
在类型为
T
的底层对象的顶部提供了一个接口

template <typename T>
class Factory
{
    public:
        // prefer copy and move, if you have C++11
        Factory(Type d) : data(std::move(d)) {} 

        // const getter
        T   get() const { return data; };

        // non-const reference getter, for modifications
        T & get()       { return data; };
    private:
        T data;
};
现在我们可以将两者独立地结合起来,创造出我们想要的东西

#include <iostream>

template <typename T>
class Factory
{
    public:
        Factory(Type d) : data(std::move(d)) {}
        T   get() const { return data; }; 
        T & get()       { return data; };
    private:
        T data;
};

template<typename Object, typename ... Args>
Factory<Object> MakeObject(Args && ... args)
{
    return Factory<Object>{ Object{ std::forward<Args>(args) ... } };
}

struct book
{
    std::string name;
    int         phone;
    book(std::string s, int t) : name(s), phone(t) {}
};

void print(Factory<book> const & k)
{
    std::cout << "[ Factory ] : " << k.get().name << ", " << k.get().phone << std::endl;
}

int main()
{
    auto obj = MakeObject<book>("Hello World", 91520);
    print(obj);
    return 0;
}
#包括
模板
阶级工厂
{
公众:
工厂(类型d):数据(std::move(d)){
T get()常量{返回数据;};
T&get(){return data;};
私人:
T数据;
};
模板
Factory MakeObject(Args&&…Args)
{
返回工厂{Object{std::forward(args)…};
}
结构体的构造
{
std::字符串名;
国际电话;
图书(std::strings,intt):姓名,电话(t){
};
无效打印(工厂常数和k)
{

std::cout我试图编译你的代码,但我得到了一些错误,比如调用'bar::bar(const char[12],int')时没有匹配的函数。
,因此我在标记为
的行中添加了
T(…)
,“不要在这里编译”。
成功了!现在代码看起来是这样的:

#include <iostream>
#include <string>
#include <algorithm>
#include <utility>

using namespace std;

template<class T>
class bar
{
public:
    template<class... Args>
    static bar<T> CreateBook(Args&&... args)
    {
        return bar<T>(T(std::forward<Args>(args)...)); // Fixed this line.
    }

    T get()
    {
        return val;
    }
private:

    bar(const T& t) :val(t) {}
    T val;

};

struct book
{
    string name;
    int phone;
    book(string s, int t) : name(s), phone(t) {}
};

void print(bar<book> k)
{
    cout << k.get().name << " " << k.get().phone << endl;
}

int main()
{
    bar<book> b = bar<book>::CreateBook("Hello World",91520);

    print(b);

    return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
模板
分类栏
{
公众:
模板
静态条CreateBook(Args&&…Args)
{
返回条(T(std::forward(args)…);//修复了此行。
}
不明白
{
返回val;
}
私人:
bar(const T&T):val(T){
T值;
};
结构体的构造
{
字符串名;
国际电话;
图书(字符串s,int t):姓名(s),电话(t){}
};
空白打印(k栏)
{

您能添加编译器的错误消息吗?@R2RT:createBook()中返回时表示初始化错误.Mohit和seccpur回复按预期工作,但我不确定哪种方式是正确的。看起来,这是工厂模式的完整实现。我想学习如何使用可变模板函数来接受工厂方法中的不同对象。感谢您的努力。谢谢,它可以工作,但为什么要使用第二个T()返回bar()构造函数中是否需要?@ark1974我认为在前面的代码中,
bar
的构造函数是用两个参数调用的,但它只有一个构造函数,只接受一个类型为
const T&
的参数
只需将1个参数传递给
bar
的构造函数,并将
T
的构造函数传递给2个参数。
#include <iostream>
#include <string>
#include <algorithm>
#include <utility>

using namespace std;

template<class T>
class bar
{
public:
    template<class... Args>
    static bar<T> CreateBook(Args&&... args)
    {
        return bar<T>(T(std::forward<Args>(args)...)); // Fixed this line.
    }

    T get()
    {
        return val;
    }
private:

    bar(const T& t) :val(t) {}
    T val;

};

struct book
{
    string name;
    int phone;
    book(string s, int t) : name(s), phone(t) {}
};

void print(bar<book> k)
{
    cout << k.get().name << " " << k.get().phone << endl;
}

int main()
{
    bar<book> b = bar<book>::CreateBook("Hello World",91520);

    print(b);

    return 0;
}