开发者
解决C++模板特例化导致的报重复定义错误
解决C++模板特例化导致的报重复定义错误
发表于2023/07/04
480

问题现象

使用毕昇编译器编译openlb时,有如下报错:

mpicxx  contactAngle2d.o  -L../../../build/generic/lib -lolb -lz -o contactAngle2d
/usr/bin/ld: ../../../build/generic/lib/libolb.a(mpiManager.o):(.rodata+0xc4): multiple definition of `olb::descriptors::data::c<2u, 5u>'; contactAngle2d.o:(.rodata+0xc4): first defined here
/usr/bin/ld: ../../../build/generic/lib/libolb.a(mpiManager.o):(.rodata+0x4): multiple definition of `olb::descriptors::data::c<2u, 9u>'; contactAngle2d.o:(.rodata+0x4): first defined here
/usr/bin/ld: ../../../build/generic/lib/libolb.a(mpiManager.o):(.rodata+0x3bc): multiple definition of `olb::descriptors::data::c<3u, 13u>'; contactAngle2d.o:(.rodata+0x3bc): first defined here
/usr/bin/ld: ../../../build/generic/lib/libolb.a(mpiManager.o):(.rodata+0x510): multiple definition of `olb::descriptors::data::c<3u, 15u>'; contactAngle2d.o:(.rodata+0x510): first defined here
/usr/bin/ld: ../../../build/generic/lib/libolb.a(mpiManager.o):(.rodata+0x134): multiple definition of `olb::descriptors::data::c<3u, 19u>'; contactAngle2d.o:(.rodata+0x134): first defined here
/usr/bin/ld: ../../../build/generic/lib/libolb.a(mpiManager.o):(.rodata+0x684): multiple definition of `olb::descriptors::data::c<3u, 27u>'; contactAngle2d.o:(.rodata+0x684): first defined here
/usr/bin/ld: ../../../build/generic/lib/libolb.a(mpiManager.o):(.rodata+0x308): multiple definition of `olb::descriptors::data::c<3u, 7u>'; contactAngle2d.o:(.rodata+0x308): first defined here
/usr/bin/ld: ../../../build/generic/lib/libolb.a(mpiManager.o):(.rodata+0x100): multiple definition of `olb::descriptors::data::t<2u, 5u>'; contactAngle2d.o:(.rodata+0x100): first defined here
/usr/bin/ld: ../../../build/generic/lib/libolb.a(mpiManager.o):(.rodata+0x70): multiple definition of `olb::descriptors::data::t<2u, 9u>'; contactAngle2d.o:(.rodata+0x70): first defined here
/usr/bin/ld: ../../../build/generic/lib/libolb.a(mpiManager.o):(.rodata+0x494): multiple definition of `olb::descriptors::data::t<3u, 13u>'; contactAngle2d.o:(.rodata+0x494): first defined here
/usr/bin/ld: ../../../build/generic/lib/libolb.a(mpiManager.o):(.rodata+0x608): multiple definition of `olb::descriptors::data::t<3u, 15u>'; contactAngle2d.o:(.rodata+0x608): first defined here
/usr/bin/ld: ../../../build/generic/lib/libolb.a(mpiManager.o):(.rodata+0x264): multiple definition of `olb::descriptors::data::t<3u, 19u>'; contactAngle2d.o:(.rodata+0x264): first defined here
/usr/bin/ld: ../../../build/generic/lib/libolb.a(mpiManager.o):(.rodata+0x83c): multiple definition of `olb::descriptors::data::t<3u, 27u>'; contactAngle2d.o:(.rodata+0x83c): first defined here
/usr/bin/ld: ../../../build/generic/lib/libolb.a(mpiManager.o):(.rodata+0x380): multiple definition of `olb::descriptors::data::t<3u, 7u>'; contactAngle2d.o:(.rodata+0x380): first defined here

问题分析

从报错日志可以看出contactAngle2d.o和mpiManager.o有重复定义的变量,查找该变量定义发现有两处地方。
1.src/dynamics/descriptorFunction.h定义了模板

template <unsigned D, unsigned Q>
constexpr int vicinity = {};

template <unsigned D, unsigned Q>
constexpr int c[Q][D] = {};

template <unsigned D, unsigned Q>
constexpr int opposite[Q] = {};

template <unsigned D, unsigned Q>
constexpr Fraction t[Q] = {};

template <unsigned D, unsigned Q>
constexpr Fraction cs2 = {};

template <unsigned D, unsigned Q>
constexpr Fraction lambda_e = {};

template <unsigned D, unsigned Q>
constexpr Fraction lambda_h = {};

2.src/dynamics/latticeDescriptors.h定义了模板特例化

template <>
constexpr int vicinity<2,9> = 1;

template <>
constexpr int c<2,9>[9][2] = {
  { 0, 0},
  {-1, 1}, {-1, 0}, {-1,-1}, { 0,-1},
  { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}
};

template <>
constexpr int opposite<2,9>[9] = {
  0, 5, 6, 7, 8, 1, 2, 3, 4
};

template <>
constexpr Fraction t<2,9>[9] = {
  {4, 9}, {1, 36}, {1, 9}, {1, 36}, {1, 9},
  {1, 36}, {1, 9}, {1, 36}, {1, 9}
};

template <>
constexpr Fraction cs2<2,9> = {1, 3};

}

mpiManager.o实例化了c&lt;2,9&gt;,contactAngle2d.o使用了特例化的c&lt;2,9&gt;,因此在链接的时候报重定义错误

解决方法:

1.使用inline修饰特例化模板。
2.删除特例化模板,统一使用模板。

收藏举报
Level 1
0
帖子
0
粉丝
0
获赞