Question

I have the following, in a header file, in one of my projects;

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

Where generic_type_test is defined as;

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

In the very same header file.

When compiling I get a bunch of multiple definition linker errors (obviously)

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

So the question is, in it's simplicity, how would I go about moving my definitions to it's own compilation unit (a ".cpp" file), while keeping my declaration in the header file?

To Jarod42

Applying you idea, yields;

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

With the lines;

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

Also I know the simplest fix, would be a forward function, but I really like the simplicity of the function pointer in this way.

Was it helpful?

Solution

I found a satisfactory solution, I simply marked all these function pointers as 'const' alike;

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

As these functions work as aliases simply, this will not prove to be any issue for me, also this ensures that the compiler doesn't allocate memory for the pointers, and thereby avoids the multiple definition linker errors.

OTHER TIPS

in header:

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

in cpp:

auto is_base_type = generic_type_test<const type_expression_base>;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top