Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.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_Inline - Fatal编程技术网

C++ 在模板中使用内联关键字有意义吗?

C++ 在模板中使用内联关键字有意义吗?,c++,templates,inline,C++,Templates,Inline,由于模板是在头文件中定义的,并且编译器能够确定内联函数是否有利,这有什么意义吗?我听说现代编译器更清楚何时内联函数,并且忽略了inlinehint 编辑:我想接受这两个答案,但这是不可能的。为了结束这个问题,我接受了 PrReNels/Stand的回答,因为它获得了最多的选票,他是正式的,但是正如我在评论中提到的,我认为“强”>小狗< /强>和组件10 的答案也是正确的,从不同的角度看。 问题是在C++语义中,在 >内联< /COD>关键字和内联的情况下,这是不严格的。strong>phres

由于模板是在头文件中定义的,并且编译器能够确定内联函数是否有利,这有什么意义吗?我听说现代编译器更清楚何时内联函数,并且忽略了
inline
hint


编辑:我想接受这两个答案,但这是不可能的。为了结束这个问题,我接受了<强> PrReNels/Stand的回答,因为它获得了最多的选票,他是正式的,但是正如我在评论中提到的,我认为“强”>小狗< /强>和<强>组件10 <强>的答案也是正确的,从不同的角度看。


问题是在C++语义中,在 >内联< /COD>关键字和内联的情况下,这是不严格的。strong>phresnel说“如果你想写就写内联”,但是
inline
的真正含义并不清楚,因为它从最初的含义演变成了一个指令,如Puppy所说,“停止编译器抱怨ODR违规行为”。

这与此无关。所有模板都已经是
inline
——更不用说从2012年起,
inline
关键字的唯一用途是阻止编译器抱怨ODR违规。您完全正确-您的当前一代编译器将知道自己应该内联什么,甚至可能在翻译单元之间也可以这样做。

正如您所建议的,
内联
只是对编译器的提示,仅此而已。它可以选择忽略它,或者实际上,选择内联未标记为内联的函数

在模板中使用
inline
过去是一种(糟糕的)解决问题的方法,即每个编译单元将为同一模板化类创建单独的对象,这将在链接时导致重复问题。通过使用
inline
(我认为)名称混乱解决了不同的问题,在链接时绕过了名称冲突,但代价是代码过于臃肿


马歇尔·克莱恩比我强。

这不是无关紧要的。不,默认情况下,并非每个函数模板都是内联的。该标准甚至在显式专门化([temp.expl.spec])中对其进行了明确说明

具备以下条件:

a、 抄送

b、 抄送

tpl.h(取自明确专业化):

\ifndef第三方物流
#定义第三方物流
模板空f(T){}
模板内联tg(T){}
模板内联void f(int){}//确定:内联
模板int g(int){}//错误:未内联
#恩迪夫
编译这个,等等,瞧:

g++ a.cc b.cc
/tmp/ccfWLeDX.o: In function `int g<int>(int)':
inlinexx2.cc:(.text+0x0): multiple definition of `int g<int>(int)'
/tmp/ccUa4K20.o:inlinexx.cc:(.text+0x0): first defined here
collect2: ld returned 1 exit status
g++a.cc b.cc
/tmp/ccfWLeDX.o:在函数“int g(int)”中:
inclinexx2.cc:(.text+0x0):'intg(int)'的多重定义
/tmp/ccUa4K20.o:inlinexx.cc:(.text+0x0):首先在这里定义
collect2:ld返回了1个退出状态
在执行显式实例化时不声明
inline
,也可能导致问题

因此总而言之:对于非完全专用的函数模板,即带有至少一种未知类型的模板,您可以省略
内联
,而不接收错误,但它们仍然不是
内联
。对于完全专门化,即仅使用已知类型的专门化,不能忽略它


建议的经验法则:如果你是认真的,就写
内联
,并保持一致。这会让你减少考虑是否去做,因为你可以。(这个经验法则符合).< /P> < P>这是C++标准所说的:

内联说明符只能应用于变量或函数的声明


该标准并未规定所有模板都是内联的。@phresnel:但模板的语义与
内联的
标记函数相同(即,可以将多个等效定义传递给链接器,链接器将选择一个)。这不是内联,而是
inline
关键字的真正功能。@BenVoigt:我知道
inline
的ODR含义。也许可以看看我下面的答案(或上面的答案,取决于选择的排序)。对于非专用模板,您当然是正确的,但它是不一样的。@ Delimg:C++中没有要求函数模板必须在头文件中实现;它可以在任何地方实现。为了反映这一点,我倾向于建议标记
inline
应该内联的内容。这通常没有什么区别,但在标准语言中,它们不一样,也不都是内联的。我接受你说“这无关紧要”的立场,但根据标准,并不是所有模板都是内联的,只是对于作为C++用户的你来说,它们看起来像是内联的。你对公认的答案的评论,即显式专业化不是模板(当然,这在被告知后是显而易见的……)可能是本页上最有用的事情。你介意把它也加到你的答案中吗?@Xeo:以前不是这样的。勾选这里:我假设最近发生了变化,这就是为什么我用过去时说话的原因。@Xeo:你能给我指出标准中规定函数模板总是内联的部分吗?因为,它们不是。@phresnel:有趣,我可以发誓我在《标准》中读到过。也许我把它和函数模板不受ODR约束的事实混淆了(
§14.5.5.1p7和p8
)。我的错,我删除了错误的注释。@组件10为什么您认为这是解决编译问题的糟糕方法编译器可能提供的标志使内联不仅仅是一个提示(例如,clang具有
-finline提示函数
)。不过,使用这样的旗帜是否是个好主意是另一个问题。人们可能会这样写,没错。但这并不意味着内在,即使看起来是这样。VANDEVORODE和JOSUTITY也完全在C++模板中声明:完整的指南,明确的专门化不是模板。@ DeimMG:但是在查找时,在一个完整的专门化上,通常的函数是首选的,所以如果它们不是模板,也不是非模板,那么它们是什么?这个答案是错误的。解释
#include "tpl.h"
#ifndef TPL_H
#define TPL_H
template<class T> void f(T) {}
template<class T> inline T g(T) {}

template<> inline void f<>(int) {} // OK: inline
template<> int g<>(int) {} // error: not inline
#endif
g++ a.cc b.cc
/tmp/ccfWLeDX.o: In function `int g<int>(int)':
inlinexx2.cc:(.text+0x0): multiple definition of `int g<int>(int)'
/tmp/ccUa4K20.o:inlinexx.cc:(.text+0x0): first defined here
collect2: ld returned 1 exit status