模板参数中 constexpr 的地址
Address of a constexpr in a template parameter
有人能解开我为什么会出现链接错误的谜团吗,如果我只在我将变量设为 const
、constexpr
或static
,但不是吗?
下面的代码片段是一个更大项目的一部分,但我提取了完全相同的结构:
CMakeLists.txt
project(fun)
add_library(fun SHARED fun.cpp)
add_executable(main main.cpp)
target_link_libraries(main fun)
fun.cpp
#include "fun.h"
BlaaUser testBlaa(int)
{
return BlaaUser();
}
fun.h
#pragma once
#include "types.h"
extern BlaaUser testBlaa(int);
main.cpp
#include "fun.h"
int main()
{
auto b = testBlaa(2);
}
types.h
#pragma once
struct P
{
char n;
};
template<const P* S>
struct Blaa
{
Blaa() {}
char blaa{S->n};
};
//constexpr
//static
//const
P p{}; // <-- Here, right now it works. If I uncomment any of the specifiers, I get errors, see below
using BlaaUser = Blaa<&p>;
如果我添加任何类型的说明符,我会收到以下错误:
Scanning dependencies of target fun
[ 25%] Building CXX object CMakeFiles/fun.dir/fun.cpp.o
[ 50%] Linking CXX shared library libfun.so
[ 50%] Built target fun
Scanning dependencies of target main
[ 75%] Building CXX object CMakeFiles/main.dir/main.cpp.o
In file included from /home/fld/work/tmpl_test/main.cpp:1:
/home/fld/work/tmpl_test/fun.h:5:17: warning: ‘BlaaUser testBlaa(int)’ used but never defined
5 | extern BlaaUser testBlaa(int);
| ^~~~~~~~
[100%] Linking CXX executable main
/usr/bin/ld: CMakeFiles/main.dir/main.cpp.o: in function `main':
main.cpp:(.text+0x12): undefined reference to `testBlaa(int)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/main.dir/build.make:104: main] Error 1
make[1]: *** [CMakeFiles/Makefile2:97: CMakeFiles/main.dir/all] Error 2
make: *** [Makefile:103: all] Error 2
我觉得它与对象的地址有关(根据标准:对于指向对象的指针,模板参数必须指定具有静态存储持续时间的完整对象的地址,并且链接(内部或外部))但我有点困惑,因为如果所有内容都在一个文件中,一切正常,当它在库中拆分时就会出现问题...
有人有解释吗?
额外的说明符(例如const
、constexpr
)使模板参数具有内部链接,随后使testBlaa(int)
具有内部链接。如果你这样做就有效
extern const P p{}
对吧?也许 相似?
有人能解开我为什么会出现链接错误的谜团吗,如果我只在我将变量设为 const
、constexpr
或static
,但不是吗?
下面的代码片段是一个更大项目的一部分,但我提取了完全相同的结构:
CMakeLists.txt
project(fun)
add_library(fun SHARED fun.cpp)
add_executable(main main.cpp)
target_link_libraries(main fun)
fun.cpp
#include "fun.h"
BlaaUser testBlaa(int)
{
return BlaaUser();
}
fun.h
#pragma once
#include "types.h"
extern BlaaUser testBlaa(int);
main.cpp
#include "fun.h"
int main()
{
auto b = testBlaa(2);
}
types.h
#pragma once
struct P
{
char n;
};
template<const P* S>
struct Blaa
{
Blaa() {}
char blaa{S->n};
};
//constexpr
//static
//const
P p{}; // <-- Here, right now it works. If I uncomment any of the specifiers, I get errors, see below
using BlaaUser = Blaa<&p>;
如果我添加任何类型的说明符,我会收到以下错误:
Scanning dependencies of target fun
[ 25%] Building CXX object CMakeFiles/fun.dir/fun.cpp.o
[ 50%] Linking CXX shared library libfun.so
[ 50%] Built target fun
Scanning dependencies of target main
[ 75%] Building CXX object CMakeFiles/main.dir/main.cpp.o
In file included from /home/fld/work/tmpl_test/main.cpp:1:
/home/fld/work/tmpl_test/fun.h:5:17: warning: ‘BlaaUser testBlaa(int)’ used but never defined
5 | extern BlaaUser testBlaa(int);
| ^~~~~~~~
[100%] Linking CXX executable main
/usr/bin/ld: CMakeFiles/main.dir/main.cpp.o: in function `main':
main.cpp:(.text+0x12): undefined reference to `testBlaa(int)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/main.dir/build.make:104: main] Error 1
make[1]: *** [CMakeFiles/Makefile2:97: CMakeFiles/main.dir/all] Error 2
make: *** [Makefile:103: all] Error 2
我觉得它与对象的地址有关(根据标准:对于指向对象的指针,模板参数必须指定具有静态存储持续时间的完整对象的地址,并且链接(内部或外部))但我有点困惑,因为如果所有内容都在一个文件中,一切正常,当它在库中拆分时就会出现问题...
有人有解释吗?
额外的说明符(例如const
、constexpr
)使模板参数具有内部链接,随后使testBlaa(int)
具有内部链接。如果你这样做就有效
extern const P p{}
对吧?也许