constexpr
在非静态变量中并不意味着inline
(C++17中的内联变量)
constexpr
在函数中意味着inline
,但是对于非静态变量却没有这种影响,尤其考虑到C++17中的内联变量。
例如,如果您采用我在 如何使用内联变量? 中发布的最小示例,并删除inline
,只剩下constexpr
,然后该变量会获得多个地址,这也是内联变量避免的主要问题。
然而,constexpr
静态变量隐式具有内联效果。
constexpr
函数的最小示例
正如在https://dev59.com/HmYq5IYBdhLWcg3wjBQM#14391320中提到的那样,inline
的主要作用不是内联函数,而是允许对函数进行多次定义, 标准引用: 如何在C++头文件中包含实现?
我们可以通过操作以下示例来观察到这一点:
main.cpp
#include <cassert>
#include "notmain.hpp"
int main() {
assert(shared_func() == notmain_func());
}
notmain.hpp
#ifndef NOTMAIN_HPP
#define NOTMAIN_HPP
inline int shared_func() { return 42; }
int notmain_func();
#endif
notmain.cpp
int notmain_func() {
return shared_func();
}
编译并运行:
g++ -c -ggdb3 -O0 -Wall -Wextra -std=c++11 -pedantic-errors -o 'notmain.o' 'notmain.cpp'
g++ -c -ggdb3 -O0 -Wall -Wextra -std=c++11 -pedantic-errors -o 'main.o' 'main.cpp'
g++ -ggdb3 -O0 -Wall -Wextra -std=c++11 -pedantic-errors -o 'main.out' notmain.o main.o
./main.out
如果我们从shared_func
中删除inline
,链接将会失败:
multiple definition of `shared_func()'
由于头文件被包含在多个.cpp
文件中,因此出现这种情况。
但是如果我们用constexpr
替换inline
,那么它再次起作用,因为constexpr
也意味着inline
。
GCC通过在ELF目标文件上将符号标记为弱来实现这一点:How can a C++ header file include implementation?
在GCC 8.3.0中进行了测试。
inline
关键字的作用。 (或者也许我误解了您的措辞。) - Luc Danton