提问人:emacs drives me nuts 提问时间:10/9/2023 最后编辑:emacs drives me nuts 更新时间:10/9/2023 访问量:24
显式模板实例化,但仍未定义引用(使用 g++,但不使用 clang++)
Explicit template instanciation but still undefined reference (with g++, but not with clang++)
问:
在下面的代码中,我得到
main.cpp: undefined reference to `(anonymous namespace)::_result<int, double>::type
PPP<int>::operator()<double>(double const&) const'
即使该模板是显式实例化的。该代码有 3 个模块:使用 、显式实例化 和 和 实例化方法模板。man.cpp
PPP<type>
ppp.cpp
PPP<int>
PPP<double>
aaa.cpp
对不起,测试用例冗长,我无法缩短它,而且失败似乎需要模板。result_type
购买力平价
#include <type_traits>
namespace
{
template<typename T> struct _prio {};
template<> struct _prio<int> { using type = std::integral_constant<int,1>; };
template<> struct _prio<double> { using type = std::integral_constant<int,2>; };
template<typename A, typename X>
struct _result
{
static constexpr bool cond = _prio<A>::type::value > _prio<X>::type::value;
using type = typename std::conditional<cond, A, X>::type;
};
} // ::anon
template<typename T>
struct PPP
{
template<typename X>
using result_type = typename _result<T,X>::type;
T t;
T operator () (const T&) const;
// aaa.cpp contains an explicit instanciation for T=int, X=double
// which is used in main().
template<typename X>
result_type<X> operator () (const X&) const;
};
// Instanciated in ppp.cpp
extern template struct PPP<int>;
extern template struct PPP<double>;
购买力.cpp
#include "ppp.h"
template<typename T>
T PPP<T>::operator () (const T& s) const
{
return s + t;
}
template struct PPP<int>;
template struct PPP<double>;
aaa.cpp
#include "ppp.h"
template<class T>
template <class X>
auto PPP<T>::operator () (const X& x) const -> result_type<X>
{
return x - (X) t;
}
extern template
auto PPP<int>::operator () (const double&) const -> result_type<double>;
template
auto PPP<int>::operator () (const double&) const -> result_type<double>;
main.cpp
#include "ppp.h"
#include <iostream>
extern template
auto PPP<int>::operator () (const double&) const -> result_type<double>;
int main (void)
{
PPP<int> pi { 10 };
std::cout << pi.t << std::endl;
std::cout << pi (22) << std::endl;
// Triggers with g++ v11.4, but not with clang++
// main.cpp: undefined reference to `(anonymous namespace)::_result<int, double>::type
// PPP<int>::operator()<double>(double const&) const'
std::cout << pi (33.3) << std::endl;
return 0;
}
编译
$ <compiler> main.cpp ppp.cpp aaa.cpp -o main.x -Wall
其中 是 或 之一。使用 clang 时,它可以很好地编译和链接,但在 g++ v11.4 中,链接器会抱怨<compiler>
g++
clang++
/usr/bin/ld: in function `main':
main.cpp: undefined reference to `(anonymous namespace)::_result<int, double>::type
PPP<int>::operator()<double>(double const&) const'
collect2: error: ld returned 1 exit status
当我添加到 g++ 选项时,然后可以看到方法的定义,但它既不是也不是。并且与该方法不再存在。使用 clang++ 时,它是可见的。-save-temps -dumpbase ""
cat aaa.s | c++filt
.global
.weak
-O2
.weak
那么有人可以解释我错过了什么吗?
我读了这篇文章,但它似乎没有为上述情况提供解决方案。
答: 暂无答案
评论
anonymous
anonymous
_result<int, double>