我有一些抽象类,我想知道是否可以在其中声明一个带有此签名的函数:
virtual auto some_function() = 0;
如果它有助于回答,我试图实现一个允许为不同类型注册回调的类,这样当调用成员模板函数时,它将查找其参数' s { {1}}在关联容器中并在其上调用其关联的回调。
对问题原始性的理解
根据N3638 - Return type deduction for normal functions
可以允许虚拟的返回类型扣除 函数(...)
所以虽然在C ++中不允许自动虚拟,但根据Jason Merrill ,这是一种可能的替代设计。
所以这个问题:是否可以使用推导的返回类型声明纯虚函数?如果不是,为什么不呢?(我已修复标题以匹配真实问题及其意图)与问题的答案不一致是否可以声明具有推导返回类型的虚函数吗
如果主持人考虑问题而不仅仅是标题,也许会有所帮助。
答案 0 :(得分:0)
这个问题没有意义。 auto
表示从初始化推断:
auto i = 1; // int
或从return
声明推断:
auto f() { return 2; } // int
纯虚函数按定义没有虚函数(*)的定义,所以它没有return
语句,所以返回类型可以不能从任何内容中推断。
您必须对C ++有不正确的理解才能认为这可行。
简答: C ++是静态输入的。
其他详细信息
注意(*):纯虚函数可以有定义,但它是 用范围调用的非虚函数的定义 解析算子:
struct Base {
virtual void f() = 0;
};
void Base::f() {
std::cout << "Base::f()\n";
}
struct Der : Base {
virtual void f();
};
void Der::f() {
cout << "Der::f()\n";
}
int main() {
Der d;
d.Base::f();
}
测试here;输出:
Base::f()
OTOH,Base::f()
无法通过虚拟呼叫机制调用:
struct Base {
Base ();
virtual void f() = 0;
};
void call (Base *p) {
cout << "Base::Base()\n";
p->f();
}
Base::Base () {
call(this);
}
测试here;生成:
Runtime error
无法虚拟调用纯虚函数。
纯虚函数返回类型可以从非虚拟定义(**)的return语句中推导出来,但它会创建另一个特例,它不会解决当前的问题(return语句是在基类中不知道。)
(**)虚拟函数不能在C ++中声明auto
,但没有强烈的理由不允许auto
虚函数。
回复评论
返回类型可以假设从派生类中推导出来。 实施
好的,我们说我们这样做:
struct Base {
virtual auto f() = 0;
};
struct Der1 : Base {
virtual int f();
};
那么Base::f()
的返回类型是int,对吗?这假设Der可以在编译器中找到,即使它在后面定义,在其他地方,并且程序是单独编译的(或者你可能建议这个功能不兼容单独的编译?)。现在这个类可以在其他地方派生出来:
struct Der2 : Base {
virtual std::string f();
};
那么Base::f()
的返回类型是什么? int,string,both,both,cat?
在C ++中,表达式必须具有明确定义的类型:声明的类型,又称编译时类型,又名静态类型。这些话是等价的。
例如,指针变量声明类型永远不会更改,而不是声明的*p
类型,但真正的运行时动态类型*p
取决于p
的值:
Base *p = 0;
// declared type of p is Base*, real type of *p is Base,
// declared type of *p is Base, real type of *p is undefined
cout << "typeid (p): " << typeid (p).name() << "\n";
p = new Der1;
// declared type of p is Base*, real type of *p is Base,
// declared type of *p is Base, real type of *p is Der1
cout << "typeid (p): " << typeid (p).name() << "\n";
cout << "typeid (*p): " << typeid (*p).name() << "\n";
编译器使用声明的类型:
public
,protected
,private
)真实类型控制运行时虚拟呼叫行为。
声明与真实类型的区别是最重要的C ++概念之一!