Перемещение определения в его собственную единицу компиляции, сохраняя объявление в заголовочном файле?

У меня есть следующее, в заголовочном файле, в одном из моих проектов;

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"), сохраняя мое объявление в заголовочном файле?

К Джароду42

Применяя свою идею, доходность;

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;

Также я знаю, что самое простое исправление - это функция пересылки, но мне действительно нравится простота указателя функции в этом смысле.

2 ответа

Решение

Я нашел удовлетворительное решение, я просто пометил все эти указатели функций как "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 ошибки компоновщика.

В заголовке:

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

в cpp:

auto is_base_type = generic_type_test<const type_expression_base>;
Другие вопросы по тегам