4

I am going a bit nuts trying to figure out why the following won't compile:

#include <iostream>
#include <array>
#include <boost/variant.hpp>
#include <forward_list>

typedef unsigned long long very_long;
typedef boost::variant< int, std::string > variants_type;
typedef std::array< variants_type, 5 > row_type;
typedef std::forward_list<row_type> rows_holder_type;

int main() {

    rows_holder_type rows;
    row_type row_data;

    row_data[0] = 0;
    row_data[1] = 0;
    row_data[2] = 0;
    row_data[3] = 0;
    row_data[4] = 0;

    rows.push_front(row_data);
}

This is the compiler error I am getting:

/usr/include/testing/test_code.o||In function 'std::array<boost::variant<int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>, 5ul>::array(std::array<boost::variant<int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>, 5ul> const&)':|
store.cpp:(.text._ZNSt5arrayIN5boost7variantIiSsNS0_6detail7variant5void_ES4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_EELm5EEC2ERKS6_[_ZNSt5arrayIN5boost7variantIiSsNS0_6detail7variant5void_ES4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_EELm5EEC5ERKS6_]+0x31)||undefined reference to 'boost::variant<int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>::variant(boost::variant<int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_> const&)'|
||=== Build finished: 1 errors, 0 warnings ===|

If I replace:

typedef boost::variant< int, std::string > variants_type;

with:

typedef boost::any variants_type;

The code compiles, but I do not want to use boost::any for performance reasons.

Jesse Good
  • 50,901
  • 14
  • 124
  • 166
user396404
  • 2,759
  • 7
  • 31
  • 42
  • 4
    It does compile, that is a linker error. – hmjd Jun 29 '12 at 21:31
  • Any suggestion on how to fix it? I'm googling how to fix linker errors as we speak, but have yet to run into the solution. – user396404 Jun 29 '12 at 21:43
  • 'fraid not. I have never used `boost::variant`. A lot of the boost stuff is header only, so no need to link anything, but not everything. The `boost::regex` is an example of that, which you need to build a library and then link with it. – hmjd Jun 29 '12 at 21:46
  • `boost::variant` is header-only as well. – ildjarn Jun 29 '12 at 21:52
  • 1
    I guess the linker error is because boost::variant is not a 'complete-type' and std::array (like most of the standard library headers) requires complete types. – A. K. Jun 29 '12 at 22:58
  • 1
    @Aditya : How could `boost::variant<>` _not_ be a complete type here? – ildjarn Jun 30 '12 at 00:06

2 Answers2

2

I tested your code with MSVC and gcc 4.7.0. MSVC compiles and links the code fine (of course with #include <string>), but gcc gives a linker error on the last line rows.push_front(row_data);. If you comment that line out, gcc accepts the code. I see no reason why gcc gives a linker error and am concluding that it is a bug with gcc. One workaround on gcc would be to change std::array to std::vector.

(From the error message I assume you are using Code::Blocks with gcc)

I've eliminated extra code and the following example still gives the linker error:

#include <boost/variant.hpp>
#include <array>

int main()
{
    std::array<boost::variant<int, double>, 5> row_type1;
    std::array<boost::variant<int, double>, 5> row_type2 = row_type1;
}
Jesse Good
  • 50,901
  • 14
  • 124
  • 166
  • This really is bizarre. I could have sworn I've used something like this with arrays before. For now, your vector "fix" is working. – user396404 Jun 30 '12 at 20:18
  • Clang 3.1 has no issues producing linkable output. – Managu Jul 01 '12 at 00:10
  • I am going to mark this as the correct answer because it did "fix" the compile error. However, I still think there has to be some way to work around this. – user396404 Jul 02 '12 at 03:45
0

You're missing #include <string>; other than that your code is fine.

ildjarn
  • 62,044
  • 9
  • 127
  • 211