C++11 将定义移动到it';在头文件中保留声明的同时,是否保留自己的编译单元?

C++11 将定义移动到it';在头文件中保留声明的同时,是否保留自己的编译单元?,c++11,linker-errors,declaration,multiple-definition-error,C++11,Linker Errors,Declaration,Multiple Definition Error,在我的一个项目的头文件中,我有以下内容: auto is_base_type = generic_type_test<const type_expression_base>; auto is_array = generic_type_test<const type_expression_tarray>; auto is_named_type = generic_type_test<const type_expression_named>;

在我的一个项目的头文件中,我有以下内容:

auto is_base_type   = generic_type_test<const type_expression_base>;
auto is_array       = generic_type_test<const type_expression_tarray>;
auto is_named_type  = generic_type_test<const type_expression_named>;
在同一个头文件中

编译时,我会遇到一堆
多定义
链接器错误(显然)

所以问题是,为了简单起见,我将如何将定义移动到它自己的编译单元(一个“.cpp”文件),同时将声明保留在头文件中

至Jarod42

运用你的想法,收获

g++ -o build/ast_helper.o -c --std=c++11 -Isrc -Ibuild build/ast_helper.cpp
build/ast_helper.cpp:11:10: error: conflicting declaration ‘auto Ast::is_base_type’
    auto is_base_type   = generic_type_test<const type_expression_base>;
         ^
In file included from build/ast_helper.cpp:1:0:
src/ast_helper.hpp:54:10: error: ‘Ast::is_base_type’ has a previous declaration as ‘bool (* Ast::is_base_type)(const Ast::type_expression&)’
    auto is_base_type   = generic_type_test<const type_expression_base>;
         ^
g++-o build/ast_helper.o-c--std=c++11-Isrc-Ibuild build/ast_helper.cpp
build/ast\u helper.cpp:11:10:错误:声明“auto-ast::is\u base\u type”冲突
自动为基本类型=通用类型测试;
^
在build/ast_helper.cpp中包含的文件中:1:0:
src/ast_helper.hpp:54:10:错误:“ast::is_base_type”之前的声明为“bool(*ast::is_base_type)(const ast::type_expression&)”
自动为基本类型=通用类型测试;
^
用线

// Below is line 11 of ast_helper.cpp
auto is_base_type   = generic_type_test<const type_expression_base>;

// Below is line 54 of ast_helper.hpp
extern decltype(generic_type_test<const type_expression_base>) is_base_type;
//下面是ast_helper.cpp的第11行
自动为基本类型=通用类型测试;
//下面是ast_helper.hpp的第54行
外部decltype(通用类型测试)是基本类型;
我也知道最简单的修复方法是向前函数,但我真的很喜欢函数指针这样简单。

在标题中:

extern decltype(generic_type_test<const type_expression_base>)* is_base_type;
extern decltype(generic\u type\u test)*是基本类型;
在cpp中:

auto is_base_type = generic_type_test<const type_expression_base>;
auto is_base_type=generic_type_test;

我找到了一个令人满意的解决方案,我只是简单地将所有这些函数指针标记为类似的“const”

const auto is_base_type   = generic_type_test<const type_expression_base>;
const auto is_array       = generic_type_test<const type_expression_tarray>;
const auto is_named_type  = generic_type_test<const type_expression_named>;
const auto is_base_type=generic_type_test;
const auto is_array=通用类型测试;
const auto被命名为\u type=generic\u type\u test;

由于这些函数只是作为别名工作,这对我来说不会有任何问题,而且这确保了编译器不会为指针分配内存,从而避免了
多定义
链接器错误。

const auto不是更好的解决方案吗,当我想要的只是特定模板版hOr better的别名时,您可以使用constexpr。(我不想改变你问题中的常数。)
auto is_base_type = generic_type_test<const type_expression_base>;
const auto is_base_type   = generic_type_test<const type_expression_base>;
const auto is_array       = generic_type_test<const type_expression_tarray>;
const auto is_named_type  = generic_type_test<const type_expression_named>;