Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.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++中的一个新容器编写迭代器。当我调用begin()和end()函数(两者都很短)时,我希望编译器将其内联。但事实并非如此。我想可能是因为迭代器作为临时对象返回,需要复制。我想也许我可以在c++11中使用右值引用,但我不熟悉它。那么,有没有一种方法可以将其内联_C++_C++11_Visual Studio 2013_Inline - Fatal编程技术网

使函数内联返回临时对象? 我正在为C++中的一个新容器编写迭代器。当我调用begin()和end()函数(两者都很短)时,我希望编译器将其内联。但事实并非如此。我想可能是因为迭代器作为临时对象返回,需要复制。我想也许我可以在c++11中使用右值引用,但我不熟悉它。那么,有没有一种方法可以将其内联

使函数内联返回临时对象? 我正在为C++中的一个新容器编写迭代器。当我调用begin()和end()函数(两者都很短)时,我希望编译器将其内联。但事实并非如此。我想可能是因为迭代器作为临时对象返回,需要复制。我想也许我可以在c++11中使用右值引用,但我不熟悉它。那么,有没有一种方法可以将其内联,c++,c++11,visual-studio-2013,inline,C++,C++11,Visual Studio 2013,Inline,代码是这样的(不完全相同,但我认为如果这个版本可以工作,我的代码也可以工作) 我正在使用VC++2013 CTP,我已经更改了编译选项,但它也不起作用 class Pointer { public: Pointer(int* p) : p(p) { (*p)++; } Pointer(const Pointer& pointer) : p(pointer.p) { (*p)++; } Pointer&

代码是这样的(不完全相同,但我认为如果这个版本可以工作,我的代码也可以工作)

我正在使用VC++2013 CTP,我已经更改了编译选项,但它也不起作用

class Pointer
{
public:
    Pointer(int* p) : p(p)
    {
        (*p)++;
    }
    Pointer(const Pointer& pointer) : p(pointer.p)
    {
        (*p)++;
    }
    Pointer& operator =(const Pointer& pointer)
    {
        (*p)--;
        p = pointer.p;
        (*p)++;
    }
    int* p;
    ~Pointer()
    {
        (*p)--;
    }
    static Pointer create(int& p)
    {
        return Pointer(&p);
    }
    static Pointer create2(int& p)
    {
        return create(p);
    }
};

int main()
{
    int p = 0;
    Pointer pointer = Pointer::create2(p);
}
这里的函数create和create2不是内联的,即使您可以看到,它非常简单


我知道这可能对我的程序的速度没有影响,但我只是想让它更好。

在C语言中,根本没有办法强制内联<代码>内联只是提示编译器执行内联,但并不要求这样做

“强制内联”的唯一方法是使用预处理器宏,但这很容易出错。错误的地方在于宏没有达到预期的效果,错误的地方在于宏实际生成的代码较慢。此外,预处理器宏不能替代成员函数


因此,如果编译器不想内联,您对此无能为力,也不应该做任何事情。

有几种情况下,microsoft编译器无法内联函数:

在某些情况下,由于机械原因,编译器不会内联特定函数。例如,编译器不会内联:

如果函数会导致SEH和C++ EH的混合。

当-GX/EHs/EHa处于启用状态时,某些具有按值传递的复制构造对象的函数

当-GX/EHs/EHa打开时,函数按值返回不可解对象。

在不使用-Og/Ox/O1/O2编译时使用内联程序集的函数

具有可变参数列表的函数

带有try(C++异常处理)语句的函数

由于函数按值返回
指针
,并且具有析构函数,因此函数不能内联

除了更改指针类之外,实际上没有什么可以做的。右值引用在这里没有帮助。我会让代码保持原样,如果您在最终产品中需要更好的性能,请尝试其他编译器

RVO可能发生在这里,但没有什么区别,因为复制的成本很低。

对于
/EH???
标志的任何组合都是正确的(并且必须指定
/EH???
,以允许任何有用的异常处理),MSVC Studio-2015以及Studio-2017 15.1和15.2版本将永远不会内联函数调用(如果存在命令)

然而,我最近发现了一个:(2016年12月)

在深度模板化的代码中,调用 函数,它只是将参数转发到另一个函数中, 这同样只是将参数转发到另一个函数中 再次只是做转发,等等。据我所知,当前版本的 如果返回一个函数,VisualC++无法在线输入这样的函数。 每当启用异常时,使用非平凡析构函数。 这通常会影响性能,尤其是在 转发不可避免地很深,并且有很多关于它的争论 不是那么小的尺寸。我非常希望即将到来的Visual C++ 2017 解决了这个问题,但似乎没有

以及一条说明将在VS2017 v15.3中修复的注释,并链接到一个注释,其中注释说明:

内联限制是因为存在异常处理。我们最近改进了我们的内联,现在它可以内联std::make_,在您提供的案例中是唯一的。请下载最新的VS 2017版本进行试用。请注意,在VS 2017 RTM中,默认情况下此新内联是关闭的,但您可以通过将标志
/d1ReturnUdtEHInline
/d2ReturnUdtEHInline
添加到cl.exe来打开它。在将来的版本中,默认情况下它将处于启用状态

请注意,
/d1
/d2
开关是编译器前端/后端的未记录开关

在VS 2017 15.3版本中,您应该期望它在默认情况下处于启用状态

因此,也许这一问题有望在VS2017 U3中得到解决。


要进行试验的两个短螺栓示例:


您的编译器设置是什么?是否检查程序集以验证调用是否未内联?我已尝试更改设置,但无效。我当然检查过装配。有一个调用指令。拷贝实际上可以省略(返回值优化/拷贝省略)。我可以在VS2013更新1(无CTP)上观察到同样的效果(未内联),使用各种编译器选项(
/Ox
,支持速度等)。我想知道的问题是,编译器为什么拒绝内联。我已检查MSDN,无法找到我的功能的原因。如果我知道原因,也许我可以修改它以满足要求?如果编译器可以执行RVO,为什么它不能内联该代码?当在OP的示例中删除dtor时,函数确实会内联(MVSC2013更新1)。感谢您的回答!那是因为异常处理?那真的很有趣。如果我使用noexcept有什么区别吗?noexcept仍然不工作。最后我找到了解决这个问题的方法。我移除析构函数并使用包装器。当使用指针对象返回时,它将转换为包装器,包装器稍后将执行
(*p)+
以及
(*p)--