将模板类与参考非类型模板参数一起使用时的链接器错误

时间:2019-01-08 21:08:46

标签: c++ templates linker c++14 non-type

我正在开发一个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,但是我想避免只将所有标头中的代码。

1 个答案:

答案 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.; 本身成为对某些静态模板变量或其他伏都教徒的引用。