Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当我可以将对象的实际类型指定为模板参数时,虚函数的内联_C++_Templates_Inlining - Fatal编程技术网

C++ 当我可以将对象的实际类型指定为模板参数时,虚函数的内联

C++ 当我可以将对象的实际类型指定为模板参数时,虚函数的内联,c++,templates,inlining,C++,Templates,Inlining,我有一个虚拟类Calculator和该类的一个示例实现MyCalculator template <class T> class Calculator{ virtual void op1() = 0; }; template <class T> class MyCalculator : public Calculator{ void op1(){ do_something(); } }; 但是,在某些情况下,我知道calc的实际类型,出于性能原因,我希

我有一个虚拟类
Calculator
和该类的一个示例实现
MyCalculator

template <class T>
class Calculator{
    virtual void op1() = 0;
};

template <class T>
class MyCalculator : public Calculator{
    void op1(){ do_something(); }
};
但是,在某些情况下,我知道
calc
的实际类型,出于性能原因,我希望将其内联。因此,我想到了以下想法:

template <class C>
void calculate(C* calc){
    calc->op1();
}
在第一个示例中,内联是不可能的,但我认为在第二个示例中,
MyCalculator
op1()
应该在
calculation()内内联


我的假设是真的吗?

您可以在C++11中将虚拟函数标记为
final
,这意味着您不能在更派生的类中重写它。然后编译器可以内联这个函数。否则,编译器无法确保您没有使用具有不同重写的更派生类型调用它,因此它无法内联。

您可以在C++11中将虚拟函数标记为
final
,这意味着您无法在更派生的类中重写它。然后编译器可以内联这个函数。否则,编译器无法确保您没有使用具有不同覆盖的更派生类型调用它,因此它无法内联。

您可以启用LTO

,

从我所读到的(但我自己还没有测试过)来看,如果链接器能够检测到实际的预期实现,那么LTO可以直接引用虚拟调用,因此在那时链接器也可以决定内联函数

您可以启用LTO

,


从我读到的(但我自己还没有测试过)来看,如果链接器能够检测到实际的预期实现,那么LTO可以直接引用虚拟调用,因此在那时,链接器也可以决定内联函数,因为编译器知道,
calculate
中的
calc
指向从
MyCalculator
派生的某个类,该类重写了
op1
。因此,它仍然别无选择,只能执行虚拟调度。进行整个程序优化的编译器可能有足够的信息来内联所有调用——但除此之外,我看不到优化的机会。你的第一句话是真的吗?我想不会,因为
op1
MyCalculator
中不是虚拟的
op1
MyCalculator
中太虚拟了。编译器都知道,
calc
calculator
中指向从
MyCalculator
派生的某个类,该类重写了
op1
。因此,它仍然别无选择,只能执行虚拟调度。进行整个程序优化的编译器可能有足够的信息来内联所有调用——但除此之外,我看不到优化的机会。你的第一句话是真的吗?我想不会,因为
op1
MyCalculator
中不是虚拟的
op1
MyCalculator
中太虚拟了。
template <class C>
void calculate(C* calc){
    calc->op1();
}
Calculator c1 = new Calculator();
calculate(c1); // no inling possible in calculate(...)

MyCalculator c2 = new MyCalculator();
calculate(c2); // inlining possible in calculate(...) ?