- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在使用模板成员函数和模板变量时遇到问题。目标是为接口(interface)创建一个模板,该接口(interface)可以被继承并链接到一个或多个在运行时初始化的服务。该接口(interface)还将数据传递给这些专门的服务(例如 MyService)。举一个更简单的例子,使用这段代码:
#include <string>
class Interface
{
public:
template <class T> bool init(T *_Service) {AttachService(*_Service);} //This function does other stuff too.
template <typename T> void AttachService(T _Service) { m_AttachedService<T> = *_Service; }
template <typename T> T AttachedService() { return m_AttachedService; }
protected:
template<typename T> static T m_AttachedService;
class InterfaceListener
{
void Received()
{
int a = 1;
std::string b = "hello";
AttachedService().setA(a);
m_AttachedService.setB(b);
};
};
};
class Service
{
Service();
~Service();
virtual void init() = 0;
};
class MyService : public Service, public Interface
{
MyService();
~MyService();
private:
int A;
std::string B;
protected:
Interface x;
public:
void init() { x.init(this);}
void setA(int a) { A = a; }
void setB(std::string b) { B = b; }
};
int main();
{
MyService myserv;
myserv.init();
}
我收到以下错误:
C2672: 'Interface::AttachedService': no matching overloaded function found
C2783: 'T Interface::AttachedService(void)': could not deduce template argument for 'T'
C2228: left of '.setA' must have class/struct/union
C3245: 'Interface::m_AttachedService': use of a variable template requires template argument list
如果能帮助理解正确使用模板,我们将不胜感激!
最佳答案
让我们从一个最小的程序开始,该程序无需执行任何有用的操作即可构建和运行。
#include <string>
class Interface
{
};
class Service
{
protected:
Service() {}
~Service() {}
virtual void init() = 0;
};
class MyService : public Service, public Interface
{
private:
int A;
std::string B;
protected:
Interface x;
public:
MyService() {}
~MyService() {}
void init() {}
void setA(int a) { A = a; }
void setB(std::string b) { B = b; }
};
int main()
{
MyService myserv;
myserv.init();
}
您会注意到,为了达到该基线,您发布的代码几乎没有变化。
Interface
是空的。Service
的成员函数在public
部分。 Service
的默认构造函数和析构函数具有空实现。MyService
的默认构造函数和析构函数位于该类的 public
部分,它们具有空实现。MyService::init()
有一个空的实现。现在我们可以开始添加更多代码了。
我将 MyService::init()
更改为:
void init() { x.init(this); }
没有其他更改,我得到以下编译器错误。
socc.cc: In member function ‘virtual void MyService::init()’:
socc.cc:25:23: error: ‘class Interface’ has no member named ‘init’
void init() { x.init(this);}
现在,Interface
需要使用 init
函数进行更新。
我添加了一个虚拟实现来插入流程向前发展。
class Interface
{
public:
template <class T> bool init(T *_Service) { return true; }
};
是时候向 Interface::init()
添加一些有用的东西了。将其更改为
template <class T> bool init(T *_Service)
{
AttachService(*_Service);
return true;
}
产生以下编译器错误,这并不奇怪。
socc.cc: In instantiation of ‘bool Interface::init(T*) [with T = MyService]’:
socc.cc:31:32: required from here
socc.cc:8:23: error: ‘AttachService’ was not declared in this scope
AttachService(*_Service);
~~~~~~~~~~~~~^~~~~~~~~~~
是时候添加 AttachService
了。将 Interface
更改为(关闭匹配你所拥有的)
class Interface
{
public:
template <class T> bool init(T *_Service)
{
AttachService(*_Service);
return true;
}
template <typename T> void AttachService(T _Service)
{
m_AttachedService<T> = *_Service;
}
protected:
template<typename T> static T m_AttachedService;
};
产生以下编译器错误。
socc.cc: In instantiation of ‘void Interface::AttachService(T) [with T = MyService]’:
socc.cc:8:10: required from ‘bool Interface::init(T*) [with T = MyService]’
socc.cc:39:32: required from here
socc.cc:14:33: error: no match for ‘operator*’ (operand type is ‘MyService’)
m_AttachedService<T> = *_Service;
^~~~~~~~~
这是有道理的。在 AttachServie
中,_Service
不是指针。
将 Inteface::AttachService
更改为:
template <typename T> void AttachService(T _Service)
{
m_AttachedService<T> = _Service;
}
使编译器错误消失,但存在链接器错误。
:socc.cc:(.rdata$.refptr._ZN9Interface17m_AttachedServiceI9MyServiceEE[.refptr._ZN9Interface17m_AttachedServiceI9MyServiceEE]+0x0): undefined reference to `Interface::m_AttachedService<MyService>'
collect2: error: ld returned 1 exit status
这是有道理的,因为我们还没有定义 static
成员变量。
添加以下行
template<typename T> T Interface::m_AttachedService;
在 Interface
定义之后立即处理链接器错误。
以下是完整程序的下一个版本,它成功构建并运行,尽管它仍然没有做任何有用的事情。
#include <string>
class Interface
{
public:
template <class T> bool init(T *_Service)
{
AttachService(*_Service);
return true;
}
template <typename T> void AttachService(T _Service)
{
m_AttachedService<T> = _Service;
}
protected:
template<typename T> static T m_AttachedService;
};
template<typename T> T Interface::m_AttachedService;
class Service
{
protected:
Service() {}
~Service() {}
virtual void init() = 0;
};
class MyService : public Service, public Interface
{
private:
int A;
std::string B;
protected:
Interface x;
public:
MyService() {}
~MyService() {}
void init() { x.init(this); }
void setA(int a) { A = a; }
void setB(std::string b) { B = b; }
};
int main()
{
MyService myserv;
myserv.init();
}
是时候将您的 AttachedService
版本添加到 Interface
template <typename T> T AttachedService() { return m_AttachedService; }
这会产生以下编译器错误。
socc.cc: In member function ‘T Interface::AttachedService()’:
socc.cc:17:73: error: missing template arguments before ‘;’ token
template <typename T> T AttachedService() { return m_AttachedService; }
这是有道理的,因为 m_AttachedService
不是成员变量而是成员变量模板。
将其更改为
template <typename T> T AttachedService() { return m_AttachedService<T>; }
删除该错误。
现在是 Interface
中的最后一部分。您发布的嵌套类 InterfaceListener
听起来不错。你有
class InterfaceListener
{
void Received()
{
int a = 1;
std::string b = "hello";
AttachedService().setA(a);
m_AttachedService.setB(b);
};
};
该类问题:
AttachedService()
是不对的,因为它是一个成员函数模板。您必须提供一个模板参数才能使用它。AttachedService()
不是static
成员函数。您需要 Interface
的实例才能进行该调用。m_AttachedService
不是成员变量。它是一个成员变量模板。您必须提供一个模板参数才能使用它。setA()
和setB()
函数仅在模板参数为MyService
时有效。在特定于某个类型的函数中包含代码没有意义。我会留给您考虑您打算如何使用 InterfaceListener
并适本地定义它的功能。在此之前,我会构建并运行以下程序。
#include <string>
class Interface
{
public:
template <class T> bool init(T *_Service)
{
AttachService(*_Service);
return true;
}
template <typename T> void AttachService(T _Service)
{
m_AttachedService<T> = _Service;
}
template <typename T> T AttachedService() { return m_AttachedService<T>; }
protected:
template<typename T> static T m_AttachedService;
};
template<typename T> T Interface::m_AttachedService;
class Service
{
protected:
Service() {}
~Service() {}
virtual void init() = 0;
};
class MyService : public Service, public Interface
{
private:
int A;
std::string B;
protected:
Interface x;
public:
MyService() {}
~MyService() {}
void init() { x.init(this); }
void setA(int a) { A = a; }
void setB(std::string b) { B = b; }
};
int main()
{
MyService myserv;
myserv.init();
}
关于c++ - 使用模板函数传递模板参数时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50161454/
Github:https://github.com/jjvang/PassIntentDemo 我一直在关注有关按 Intent 传递对象的教程:https://www.javacodegeeks.c
我有一个 View ,其中包含自动生成的 text 类型的 input 框。当我单击“通过电子邮件发送结果”按钮时,代码会将您带到 CalculatedResults Controller 中的 Em
我有一个基本的docker镜像,我将以此为基础构建自己的镜像。我没有基础镜像的Dockerfile。 基本上,基本镜像使用两个--env arg,一个接受其许可证,一个选择在容器中激活哪个框架。我可以
假设我想计算 2^n 的总和,n 范围从 0 到 100。我可以编写以下内容: seq { 0 .. 100 } |> Seq.sumBy ((**) 2I) 但是,这与 (*) 或其他运算符/函数不
我有这个网址: http://www.example.com/get_url.php?ID=100&Link=http://www.test.com/page.php?l=1&m=7 当我打印 $_G
我想将 window.URL.createObjectURL(file) 创建的地址传递给 dancer.js 但我得到 GET blob:http%3A//localhost/b847c5cd-aa
我想知道如何将 typedef 传递给函数。例如: typedef int box[3][3]; box empty, *board[3][3]; 我如何将 board 传递给函数?我
我正在将一些代码从我的 Controller 移动到核心数据应用程序中的模型。 我编写了一个方法,该方法为我定期发出的特定获取请求返回 NSManagedObjectID。 + (NSManagedO
为什么我不能将类型化数组传递到采用 any[] 的函数/构造函数中? typedArray = new MyType[ ... ]; items = new ko.observableArray(ty
我是一名新的 Web 开发人员,正在学习 html5 和 javascript。 我有一个带有“选项卡”的网页,可以使网页的某些部分消失并重新出现。 链接如下: HOME 和 JavaScript 函
我试图将对函数的引用作为参数传递 很难解释 我会写一些伪代码示例 (calling function) function(hello()); function(pass) { if this =
我在尝试调用我正在创建的 C# 项目中的函数时遇到以下错误: System.Runtime.InteropServices.COMException: Operation is not allowed
使用 ksh。尝试重用当前脚本而不修改它,基本上可以归结为如下内容: `expr 5 $1 $2` 如何将乘法命令 (*) 作为参数 $1 传递? 我首先尝试使用“*”,甚至是\*,但没有用。我尝试
我一直在研究“Play for Java”这本书,这本书非常棒。我对 Java 还是很陌生,但我一直在关注这些示例,我有点卡在第 3 章上了。可以在此处找到代码:Play for Java on Gi
我知道 Javascript 中的对象是通过引用复制/传递的。但是函数呢? 当我跳到一些令人困惑的地方时,我正在尝试这段代码。这是代码片段: x = function() { console.log(
我希望能够像这样传递参数: fn(a>=b) or fn(a!=b) 我在 DjangoORM 和 SQLAlchemy 中看到了这种行为,但我不知道如何实现它。 最佳答案 ORM 使用 specia
在我的 Angular 项目中,我最近将 rxjs 升级到版本 6。现在,来自 npm 的模块(在 node_modules 文件夹内)由于一些破坏性更改而失败(旧的进口不再有效)。我为我的代码调整了
这个问题在这里已经有了答案: The issue of * in Command line argument (6 个答案) 关闭 3 年前。 我正在编写一个关于反向波兰表示法的 C 程序,它通过命
$(document).ready(function() { function GetDeals() { alert($(this).attr("id")); } $('.filter
下面是一个例子: 复制代码 代码如下: use strict; #这里是两个数组 my @i =('1','2','3'); my @j =('a','b','c'); &n
我是一名优秀的程序员,十分优秀!