【问题标题】:Moving definition to it's own compilation unit, while keeping declaration in header file?将定义移动到它自己的编译单元,同时将声明保留在头文件中?
【发布时间】:2013-08-15 23:24:03
【问题描述】:

我的一个项目的头文件中有以下内容;

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>;

其中generic_type_test定义为;

template<typename T>
bool generic_type_test(const type_expression& arg)
{
    return generic_test<type_expression, T>(arg);
}

在同一个头文件中。

编译时我收到一堆 multiple definition 链接器错误(显然)

st_pp.o:ast_pp.cpp:(.data+0x0): multiple definition of `Ast::is_base_type'
st_helper.o:ast_helper.cpp:(.data+0x0): first defined here

所以问题是,简单来说,我将如何将我的定义移动到它自己的编译单元(“.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>;
         ^

用线条;

// 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;

我也知道最简单的解决方法是转发函数,但我真的很喜欢这种函数指针的简单性。

【问题讨论】:

    标签: c++11 linker-errors declaration multiple-definition-error


    【解决方案1】:

    我找到了一个令人满意的解决方案,我只是将所有这些函数指针都标记为“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>;
    

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

    【讨论】:

      【解决方案2】:

      在标题中:

      extern decltype(generic_type_test<const type_expression_base>)* is_base_type;
      

      在 cpp 中:

      auto is_base_type = generic_type_test<const type_expression_base>;
      

      【讨论】:

      • 当我想要的只是 h 的特定模板版本的别名时,const auto 不是更好的解决方案吗
      • 或者更好,你可以使用 constexpr。 (我不想改变你问题中的常量。)
      猜你喜欢
      • 1970-01-01
      • 2010-12-26
      • 2022-07-19
      • 1970-01-01
      • 2012-08-27
      • 1970-01-01
      • 1970-01-01
      • 2014-09-06
      • 1970-01-01
      相关资源
      最近更新 更多