【问题标题】:Undefined reference to extern template constexpr constructor对外部模板 constexpr 构造函数的未定义引用
【发布时间】:2019-07-10 04:47:24
【问题描述】:

这是我能生成的显示此行为的最小示例:

foo.h

#pragma once

#include <string>

template <int I>
struct foo
{
    constexpr explicit foo(int k)
        : j(k + I)
    { }

    std::string to_string() const;

private:

    int j;
};

extern template struct foo<0>;

constexpr foo<0> operator"" _foo0(unsigned long long int v)
{
    return foo<0>(static_cast<int>(v));
}

foo.cpp

#include "foo.h"

template <int I>
std::string foo<I>::to_string() const
{
    return std::to_string(j);
}

template struct foo<0>;

bar.h

#pragma once

#include "foo.h"
#include <vector>

template <typename T>
struct bar
{
    explicit bar(int i);

private:

    std::vector<T> vec;
};

extern template struct bar<foo<0>>;

bar.cpp

#include "bar.h"

template <typename T>
bar<T>::bar(int i)
{
    vec.push_back(T{i});
}

template struct bar<foo<0>>;

这个用法如下:

main.cpp

#include "bar.h"

int main()
{
    bar<foo<0>> b2(5);
}

在 GCC 下编译(我已经尝试过 7.4.0 和 8.3.0):

g++-8 foo.cpp bar.cpp main.cpp -std=c++14 -Wall -Werror -o test

给出错误:

bar.cpp:(.text._ZN3barI3fooILi0EEEC2Ei[_ZN3barI3fooILi0EEEC5Ei]+0x3c): 对 `foo::foo(int)' 的未定义引用

Clang 版本 4 到 7 似乎接受了这一点。

两个小改动让 GCC 接受它:

  1. 删除constexpr operator"" 定义,或
  2. operator""foo 构造函数更改为inline 而不是constexpr

这是否合法,GCC 是否有正当理由拒绝原样?

【问题讨论】:

  • 编译所有.cpp文件是否也会出现问题(不通过共享库)
  • @M.M 是的,同样的问题。我会更新问题。
  • 请注意,它适用于-std=c++17

标签: c++ templates constexpr


【解决方案1】:

我对你的资源做了很多尝试,得到了以下结果:

gcc9.1.0编译没有问题!

现在对 gcc 8.3.0 感到好奇:

g++ main.cpp foo.cpp bar.cpp -std=c++14 -Wall // fails: undef reference

如你所说失败!

但没有 -Wall 它可以编译!

g++ main.cpp foo.cpp bar.cpp -std=c++14  // compiles, no linker error!

还有

g++ main.cpp foo.cpp bar.cpp -std=c++17 -Wall // compiles, no linker error!

我不知道为什么标志 -Wall 与生成的中间文件有任何关系。 -Wall不应该影响任何生成的代码,因为它只是一个诊断的东西。所以对我来说,这只是一个 gcc 错误!所以请填写错误报告!

【讨论】:

    猜你喜欢
    • 2012-02-03
    • 2020-01-29
    • 1970-01-01
    • 2017-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多