【问题标题】:Template member std::function of none templated class无模板类的模板成员 std::function
【发布时间】:2020-01-26 06:29:13
【问题描述】:

我有一个类,它有一个模板函数

class DialogManager
{
public:
    template<class T>
    using TimeoutCallback = std::function<void (T)>;

    DialogManager();
    virtual ~DialogManager();

    template<class T>
    void SetTimeoutCallback(TimeoutCallback<T> callback);

    int GetDialoge(T obj);

private:
    TimeoutCallback mTimeoutCallback;
}

我得到以下错误:

错误:模板名称“DialogManager::TimeoutCallback”的使用无效 没有参数列表

我已将代码更改为

template<class T>
TimeoutCallback<T> mTimeoutCallback;

但我遇到了另一个编译器的错误

错误:数据成员“mTimeoutCallback”不能是成员模板

示例用法是

#include <DialogManager.h>

class foo()
{
public:
    foo()
    {
        DialogManager* dialog = new DialogManager();
    }

    DialogManager* mDialogManager;
};

struct data
{
    data() {}
};

int main()
{
    Foo* f1 = new Foo();
    auto a1 = f1->mDialogManager->GetDialoge(1);
    auto b1 = f1->mDialogManager->GetDialoge("test");

    Foo* f2 = new Foo();

    data d;
    auto a2 = f2->mDialogManager->GetDialoge(d);
    auto b2 = f2->mDialogManager->GetDialoge(45.231);

    return 0;
}

`

【问题讨论】:

  • 您很可能希望 DialogManager 成为类模板。从您的代码中删除行 template&lt;class T&gt; 并在列表的第一行之前添加一行 template&lt;class T&gt;。如果您确定不希望这样,则需要在此处说明您的用例更好一些。

标签: c++ templates c++14 std-function


【解决方案1】:

如果您想在类的不同部分共享相同的模板类型,请将其设为模板类而不是模板函数。

#include <functional>

template<class T>
class DialogManager
{
public:
    using TimeoutCallback = std::function<void (T)>;

    DialogManager();
    virtual ~DialogManager();

    void SetTimeoutCallback(TimeoutCallback callback);

private:
    TimeoutCallback mTimeoutCallback;
};

【讨论】:

    【解决方案2】:

    如果您正在编写一个类头文件,那么您通常希望对类进行模板化,并将模板类型的名称用作该文件中的变量类型。然后,在 coder 文件中,您可以定义类似于您在提供的代码中的方法。看起来您修复了第一个编译错误,而第二个错误似乎是因为您正在模板头文件中的各个方法。这是一个模板化头文件的基本示例:

    `template<typename T>
    class Node{
        private:
            T m_entry;
            Node<T>* m_nextNodePtr;
        public:
            T getEntry() const;
            void setEntry(T newEntry);
            //more
    }`
    

    这是头文件随附的编码器文件:

    `template<typename T>
    T Node<T>::getEntry() const{
        return m_entry;
    }
    
    template<typename T>
    void Node<T>::setEntry(T newEntry){
        m_entry = newEntry;
        return;
    
    //more
    }`
    

    希望这会有所帮助!

    【讨论】:

    • 我无法将模板作为我的课程
    【解决方案3】:

    你的mTimeoutCallback是一个模板成员变量;解决using,这是一个

    template<class T>
    std::function<void (T)> mTimeoutCallback;
    

    不幸的是 (a) 模板变量仅从 C++14 开始可用(并且您标记了 C++11)并且 (b) 模板变量只有在 static 时才能成为类/结构的成员。

    所以你的错误。

    【讨论】:

    • 由于我的样本,我无法将其设为静态
    • @MajidDarvishan - 但您不能将模板设为非静态成员。您可以按照其他答案中的建议将模板设为课程吗?在这种情况下,您有一个普通(非模板)成员。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多