gpt4 book ai didi

c++ - 模板链接器错误 : Undefined symbols (linker error), 但所有内容都在一个文件中

转载 作者:行者123 更新时间:2023-11-30 03:19:51 33 4
gpt4 key购买 nike

编译和链接我定义自定义文字的唯一文件失败。该文件由自定义文字定义 (operator"") 组成,在此之前有一个模板类将数字 (typename ... Chars) 转换为数字类型 NumberT:

#include <cstdint>
#include <chrono>
#include <limits>


using Du = std::chrono::duration<uint16_t>;


template <typename NumberT, size_t Depth, char ... String>
struct _StringToNumber;

template <typename NumberT, size_t Depth, char Head, char ... Tail>
struct _StringToNumber<NumberT, Depth, Head, Tail ...> {
static_assert('0' <= Head <= '9', "unsupported character in unsigned number literal");

using next = _StringToNumber<NumberT, Depth+1, Tail ...>;

const static size_t total_depth = next::total_depth;

const static NumberT order_value = (total_depth-Depth-1)*(Head - '0');

static_assert(std::numeric_limits<NumberT>::max() - next::value >= order_value, "literal does not fit the underlying type");

const static NumberT value = order_value + next::value;

};

template <typename NumberT, size_t Depth>
struct _StringToNumber<NumberT, Depth> {
const static size_t total_depth = Depth;
const static NumberT value = 0;
};

template <typename NumberT, char ... Chars>
using StringToNumber = _StringToNumber<NumberT, 0, Chars ...>;


template <char ... Chars>
Du operator "" _du () { // my custom literal
return Du(StringToNumber<Du::rep, Chars ...>::value);
}


int main() {
1_du; // Undefined symbols for architecture x86_64: "_StringToNumber<unsigned short, 0ul, (char)49>::value"
StringToNumber<uint16_t, '2'>::value; // apparently works

return 0;
}

链接器错误:

Undefined symbols for architecture x86_64:
"_StringToNumber<unsigned short, 0ul, (char)49>::value", referenced from:
std::__1::chrono::duration<unsigned short, std::__1::ratio<1l, 1l> > operator"" _du<(char)49>() in scratch_1-71f359.o
ld: symbol(s) not found for architecture x86_64

奇怪的是,如果我用 e 替换 Du 和 Du::rep,我不会收到错误。 G。 uint16_t.

命令g++ -std=c++17 thefile.cpp

$ g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 10.0.0 (clang-1000.11.45.5)
Target: x86_64-apple-darwin18.0.0
Thread model: posix

最佳答案

struct 定义中的以下语法:

const static NumberT value = 0;

是带有初始值设定项的声明,不是定义。也就是说,编译器可以将其值用于优化目的,但是一旦 value 被 ODR 使用(例如,绑定(bind)到引用),该实体必须在内存中有一个地址。通过使用 std::chrono::duration 作为 operator"" 的结果,您强制 value 的引用约束>duration 的构造函数接受一个参数,因此允许链接器提示缺少定义。为了提供定义,将以下行放在 struct 本身的定义之后:

template <typename NumberT, size_t Depth>
const NumberT _StringToNumber<NumberT, Depth>::value;

特化之后:

template <typename NumberT, size_t Depth, char Head, char ... Tail>
const NumberT _StringToNumber<NumberT, Depth, Head, Tail ...>::value;

或者使所有声明内联 ( ):

template <typename NumberT, size_t Depth>
struct _StringToNumber<NumberT, Depth> {
inline const static size_t total_depth = Depth;
inline const static NumberT value = 0;
};

另请注意,以下划线后跟大写字母开头的标识符是为实现保留的。

关于c++ - 模板链接器错误 : Undefined symbols (linker error), 但所有内容都在一个文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53363248/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com