【问题标题】:Templates with different parameters具有不同参数的模板
【发布时间】:2017-06-13 14:36:03
【问题描述】:

我找不到一种方法可以将以下模板变成只有一个具有相同效果的模板。我的目标是实例化表单的子类。子类可以有没有到两个参数的构造函数。

template<class T> bool Session::OpenForm() {
    Form* form = new T();
    return OpenForm(form);
}

template<class T, class U> bool Session::OpenForm(U parameter) {
    Form* form = new T(parameter);
    return OpenForm(form);
}

template<class T, class U, class V> bool Session::OpenForm(U parameter1, V parameter2) {
    Form* form = new T(parameter1, parameter2);
    return OpenForm(form);
}

我使用这样的模板:

session->OpenForm<SubForm>();
session->OpenForm<OtherSubForm>("Title");

环顾四周,我认为使用可选参数可以解决问题,但我无法使其正常工作。我试过这样的事情:

template<class T, class U = T, class V = T> 
bool Session::OpenForm(U parameter1 = NULL, V parameter2 = NULL) {
    Form* form = NULL;

    if(parameter2 != NULL) form = new T(parameter1, parameter2);
    else if(parameter1 != NULL) form = new T(parameter1);
    else form = new T();
}

有没有办法只使用一个模板来处理这个问题?或者也许只是一个更好的方法?

我使用 C++03。

谢谢

【问题讨论】:

  • 3 个重载有什么问题? (U parameter1 = NULL, V parameter2 = NULL) 看起来很丑恕我直言。 NULL 只能用于指针类型。如果它们不是指针 NULL 没有多大意义,即使它确实可以编译。请记住,您始终可以从较少参数的函数中调用较多的参数函数,以避免代码重复。
  • 当然,在 C++(即当前标准)中,人们会使用可变参数模板。所以对于任何使用 C++11 及更高版本的人来说,这确实不是问题。
  • 3 个重载很好,但我担心以后会出现更多。在这种情况下,参数确实是指针。我想我至少会坚持我的解决方案,直到我可以访问 C++11。谢谢

标签: c++ templates optional-parameters c++03


【解决方案1】:

我将从技术上回答你的问题,但不是解决问题的关键 --- 你真正想要的是可变参数模板,它是 C++11 的一个特性。

相反,您可以将所有工作交给每个附加 SubForm 类型的实现者:每个新的 SubForm 类必须有一个构造函数,该构造函数接受一个 args 结构,SubForm 可以使用该结构来初始化自己。

例如:

struct SubFormArgs{};
struct OtherSubFormArgs{
    OtherSubFormArgs(std::string s) : param1(s){}
    std::string param1;
};

struct Form{};

struct SubForm : Form{
    SubForm(SubFormArgs){}
};

struct OtherSubForm : Form{
    OtherSubForm(OtherSubFormArgs args): myStr(args.param1){}
    std::string myStr;
}

SubForm 使用SubFormArgs 构造自己,OtherSubForm 使用OtherSubFormArgs 构造自己。

这简化了您的 OpenForm 函数,如下所示:

bool OpenForm(Form* f){/*...*/}

struct Session
{
    template<class T, class U>
    bool OpenForm(U ctor_params)
    {
        Form* form = new T(ctor_params);
        return ::OpenForm(form);
    }
};

还有一个测试:

Session* session = new Session();
session->OpenForm<SubForm>(SubFormArgs());
session->OpenForm<OtherSubForm>(OtherSubFormArgs("Title"));

Demo

【讨论】:

  • 非常有用,谢谢!我想我现在会坚持使用我的多个模板,并在我可以访问 C++11 时回来 :)
猜你喜欢
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
  • 2011-10-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多