Uploaded image for project: 'C++ Driver'
  1. C++ Driver
  2. CXX-956

Compile error with clang/libc++ on Linux due to ambiguous call to 'append' member function

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 3.0.1
    • Component/s: Build
    • Labels:
      None

      When compiling with clang and libc++ on Linux, the build stops with an error because of an ambiguous call to the member function append() of the bsoncxx::builder::core class:

      mongo-cxx-driver-r3.0.1/src/bsoncxx/builder/stream/value_context.hpp:70:16: error: call to member function 'append' is ambiguous
              _core->append(std::forward<T>(t));
      

      The line that causes the call is in the src/mongocxx/collection.cpp file at line 210:

              filter_builder << "$maxTimeMS" << options.max_time()->count();
                                                                   ^
      

      The type of options.max_time() is std::chrono::milliseconds, and according to cppreference's std::chrono::duration entry, std::chrono::milliseconds is a helper type for a std::chrono::duration with an instantiation of duration</*signed integer type of at least 45 bits*/, std::milli>. This means that options.max_time()->count should return a signed integer type of at least 45 bits.

      From looking at the source code of the C++ standard library implementations, the chrono header in libc++ has std::chrono::milliseconds defined as:

      typedef duration<long long, milli> milliseconds;
      

      whereas stdlibc++ has a chrono header that has it defined as

      typedef duration<int64_t, milli> milliseconds;
      

      Both of the implementations are compliant with the C++ standard. When building against stdlibc++, the parameter value returned by the count() function should match with the candidate function void append(std::int64_t value). However, in this case where the code is being built with libc++, it seems as though the long long underlying representation and value returned by count() causes it not to match with any of the candidate functions for bsoncxx::builder::core::append().

      I was able to apply a static cast of int64_t to the result of the function call, and this allowed that code to compile.

      filter_builder << "$maxTimeMS" << static_cast<int64_t>(options.max_time()->count());
      

      Here are the files and lines with relevant usages of the count() function:

      /tmp/source_install/mongo-cxx-driver-r3.0.1/src/mongocxx/collection.cpp:210
      /tmp/source_install/mongo-cxx-driver-r3.0.1/src/mongocxx/collection.cpp:291
      /tmp/source_install/mongo-cxx-driver-r3.0.1/src/mongocxx/collection.cpp:583
      /tmp/source_install/mongo-cxx-driver-r3.0.1/src/mongocxx/collection.cpp:736
      
          filter_builder << "$maxTimeMS" << options.max_time()->count();
      
      
      /tmp/source_install/mongo-cxx-driver-r3.0.1/src/mongocxx/options/modify_collection.cpp:38
      
          << "expireAfterSeconds" << seconds.count() << finalize);
      
      

      Applying the same static cast for an int64_t allows the build to complete without any errors.

            Assignee:
            andrew.morrow@mongodb.com Andrew Morrow (Inactive)
            Reporter:
            jwang Jonathan Wang
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: