我正在开发一个C ++库,需要在其中向用户提供类模板。
此类的模板参数是一个引用。但是,我收到一个链接器错误。这是一个最小的测试用例:
test.hh
#ifndef TEST_HH_
#define TEST_HH_
template <double const& val>
struct A{};
constexpr double zero = 0.;
A<zero> foo();
#endif // TEST_HH_
test.cpp
#include "test.hh"
A<zero> foo(){ return A<zero>(); }
main.cpp
#include "test.hh"
int main()
{
foo();
}
在编译这段代码时,我得到警告:
'A<zero> foo()' used but never defined
后面是链接器错误:
undefined reference to foo()
我试图用int代替double:
template <int val>
struct A{};
并且它链接了(当传递int
作为c的参数时),但是我真的需要一个double
。
当模板类涉及链接错误时,我也尝试了一种常见的解决方案,我在foo()
中实现了test.hh
函数,而不是test.cpp
,但是我想避免只将所有标头中的代码。
答案 0 :(得分:0)
很高兴这没有联系!可能会更糟...
问题基本上是<script>
$(document).ready(function () {
var table = $('#stock').DataTable({
rowReorder: {
selector: 'td:nth-child(2)'
},
responsive: true
});
setTimeout(table.columns.adjust().draw(), 300)
$('#stock').resize()
});
</script>
和test.cpp
都具有名为main.cpp
的不同对象。这是违反ODR的行为-您对该变量有多个定义,并且由于::zero
的模板参数A<zero>
是对中不同对象的引用,因此从技术上讲A
最终是不同的类型不同的翻译单位。
希望该解释清楚说明了val
正常工作的原因。
在C ++ 17中,您需要:
A<int>
在C ++ 14中,您需要在一个翻译单元中添加一个定义,或者执行其他某种魔术,例如使inline constexpr double zero = 0.;
本身成为对某些静态模板变量或其他伏都教徒的引用。