简体   繁体   中英

How can I call my template variadic functor object? I am confused about the parameters and the calling synthax I should use.

I have created this variadic template class with a functor to act as a factory for another object. My class compiles fine, but I can't figure out the right syntax to use in order to instantiate the object and call its functor operator. This is my template class.

// factory
template <typename T, typename... Targs>
class MakeTreeNodeEntry {
public:
MakeTreeNodeEntry();
Wt::WTreeTableNode* operator()(Wt::WTreeTableNode *parent, T t, Targs... Fargs) const;

protected:
    template <typename T, typename... Targs>
    void addColumnValue(Wt::WTreeTableNode *node, int iindex, T t) {
        Wt::WText* ptextwidget = new Wt::WText(static_cast<const char*>(t));
        //ptextwidget->addStyleClass("ellipsis");
        node->setColumnWidget(++iindex, ptextwidget);
    }

    template <typename T, typename... Targs>
    void addColumnValue(Wt::WTreeTableNode *node, int iindex, T t, Targs... Fargs) {
        Wt::WText* ptextwidget = new Wt::WText(static_cast<const char*>(t));
        //ptextwidget->addStyleClass("ellipsis");
        node->setColumnWidget(++iindex, ptextwidget);
        addColumnValue(node, iindex, Fargs...); // recursive call
    }

    friend class Wt::WTreeNode;
private:

};

    template <typename T, typename... Targs>
inline MakeTreeNodeEntry<T, Targs...>::MakeTreeNodeEntry(){}

template <typename T, typename... Targs>
inline
     Wt::WTreeTableNode* MakeTreeNodeEntry<T, Targs...>::operator()
     (Wt::WTreeTableNode *parent, T t, Targs... Fargs)
    const {

    int i = 0;
    const char* pvalue = static_cast<const char*>(t);
    Wt::WTreeTableNode *node = new Wt::WTreeTableNode(pvalue, 0, parent);
    //node->label()->addStyleClass("truncate");
    addColumnValue(node, i, Fargs...);

    Wt::WInteractWidget *itemwidget;
    if (Wt::WApplication::instance()->environment().ajax())
        itemwidget = node->impl();
    else
        itemwidget = node->label();

    itemwidget->clicked().connect(std::bind([=]() {
        int ii = 0;
    }));

    return node;
}




// trying to call in the main
int main()
{
    Wt::WTreeTableNode *root = new Wt::WTreeTableNode("User's Ads");
    treeTable->setTreeRoot(root, "Ads");

    Wt::WTreeTableNode *group;

    group = new Wt::WTreeTableNode("Agriculture", 0, root);
    MakeTreeNodeEntry<const char*, const char*> mk;
    mk(group, "P&G Credits House", "Best of Market Offering", 
    "2016/01/04", "2016/03/04", "178", "2016/01/04");

    ...
    return 0;
}

The problem is that you have two versions of variadic declarations, one for the class and another one its methods . I'm not sure if you really want that.

The calls mk(group, "P&G Credits House", "Best of Market Offering", "2016/01/04", "2016/03/04", "178", "2016/01/04"); call gets many const char* , while your class instantiation only used two in case of akeTreeNodeEntry<const char*, const char*> mk; . Because operator() does not have another template declaration, the compiler will bind that to the ones used by class. Because you declared two const char* it is going to assume that operator() gets two template arguments.

In my opinion you should remove the template class definition ( template <typename T, typename... Targs> class MakeTreeNodeEntry ) -> ( class MakeTreeNodeEntry ) and use the the variadic template declaration only with the methods. That way you just build up your mk without template parameters, but use the operator() with as many parameters as you like, because that method will use variadic templates like the other methods.

operator() needs a variadic declaration as well for that to get it working like this template <typename T, typename... Targs> Wt::WTreeTableNode* operator()(Wt::WTreeTableNode *parent, T t, Targs... Fargs) const;

The other alternative to make your code run correctly is to set the variadic template declaration to the whole class, but remove the template declaration of all the methods. With that declaration your calls will result into:

MakeTreeNodeEntry<const char*, const char*, const char*, const char*, const char*, const char*> mk;
mk(group, "P&G Credits House", "Best of Market Offering", 
"2016/01/04", "2016/03/04", "178", "2016/01/04");

Which is not that flexible or elegant. So I think your class should not use templates declarations at all but your methods should be able to use variadic templates.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM