Redefinition of tuple when using gtest and google sparsehash

2.9k views Asked by At

All test cases that somehow include <gtest/gtest.h> and <google/dense_hash_map> fail to build for me. Usually the later is included indirectly but I can reproduce the problem like this:

#include <gtest/gtest.h>
#include <google/dense_hash_map>

TEST(SparsehashTest, justPass) {
  ASSERT_TRUE(true);
};


int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

The problem:

In file included from /usr/include/c++/5/tr1/functional:39:0,
                 from /usr/local/include/sparsehash/dense_hash_map:106,
                 from /usr/local/include/google/dense_hash_map:34,
                 from /home/me/xxx/test/SparsehashTest.cpp:6:
/usr/include/c++/5/tr1/tuple:130:11: error: redefinition of ‘class std::tuple< <template-parameter-1-1> >’
     class tuple : public _Tuple_impl<0, _Elements...>
           ^
In file included from /home/me/xxx/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:697:0,
                 from /home/me/xxx/third_party/googletest/googletest/include/gtest/internal/gtest-internal.h:40,
                 from /home/me/xxx/third_party/googletest/googletest/include/gtest/gtest.h:58,
                 from /home/me/xxx/test/SparsehashTest.cpp:5:
/usr/include/c++/5/tuple:463:11: error: previous definition of ‘class std::tuple< <template-parameter-1-1> >’
     class tuple : public _Tuple_impl<0, _Elements...>

So sparsehash includes /usr/include/c++/5/tr1/tuple whereas gtest includes /usr/include/c++/5/tuple and puts it in the tr1 namespace in gtest-port.h:

...
697: #include <tuple>
698: // C++11 puts its tuple into the ::std namespace rather than
699: // ::std::tr1.  gtest expects tuple to live in ::std::tr1, so put it there.
700: // This causes undefined behavior, but supported compilers react in
701: // the way we intend.
702: namespace std {
703: namespace tr1 {
704: using ::std::get;
705: using ::std::make_tuple;
706: using ::std::tuple;
707: using ::std::tuple_element;
708: using ::std::tuple_size;
709: }
...

I can understand why this causes problems, but so far I don't understand why this only seems to happen in my setup. I have google-sparsehash installed regularly (git clone and then ./configure && make && sudo make install) and my project is a CMake project that has a git submode for googletest and builds it as a dependency / subfolder. This setup works as intended for all tests that do not (indirectly) include the sparsehash headers.

EDIT: So it seems to compile if I add -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=0 as compiler flags. I'm not sure why this is necessary and if it's the right thing to do here

2

There are 2 answers

0
Michael Doubez On

The full set of defines altering gtest due to environmment are shown in gtest-port.h file. The documentation also gives you the detail of TR1 tuple configuration.

Depending on your environment. You may be doing the right thing. GoogleTest is supposed to do the detection for you, in practice I've rarely seen it work and I usually define the same flags as yours.

0
Bret On

I found this thread because I had the same issue, and it provided enough clues that I managed to fix my issue by requesting that sparsehash be compiled with the c++11 compiler option:

./configure CXXFLAGS='-std=c++11'