implicit instantiation of undefined template: Boos

2019-02-26 05:53发布

问题:

I was trying to compile some code that uses Boost (1.49), with Clang(& libc++) from trunk. The problematic code boils down to the following:

#include <memory>
#include <boost/signals2.hpp>

int main()
{
    std::shared_ptr<int> s;
}

When compiled with Clang, the following message is emmited:

$ clang++ -I/home/alexander/usr/local/include --stdlib=libc++ -std=c++0x signals2-bug.cpp   -o signals2-bug
signals2-bug.cpp:6:26: error: implicit instantiation of undefined template
      'std::shared_ptr<int>'
    std::shared_ptr<int> s;
                         ^
/home/alexander/usr/local/include/boost/signals2/detail/foreign_ptr.hpp:24:30: note: 
      template is declared here
  template<typename T> class shared_ptr;
                         ^

The offending lines in boost/signals2/detail/foreign_ptr.hpp are:

#if !defined(BOOST_INTEL_STDCXX0X)
namespace std
{
  template<typename T> class shared_ptr;
  template<typename T> class weak_ptr;
}
#endif

Now who's to blame?

Two things come to mind:

  1. Why does the Boost.Signals header feel the need to declare an own shared_ptr? What's the gain?
  2. The line in Boost.Signals looks like a simple forward declaration. Why would that be problematic, if it comes after the template definition?

EDIT

This appears to be a Boost.Signals2 bug, because the declaration of things in the std:: namespace results in undefined behaviour, according to the ISO/IEC C++ 2011 Standard, section 17.6.4.2.1:

The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.

A ticket in the Boost bug tracker has been created: https://svn.boost.org/trac/boost/ticket/6655

Please note, that a Clang bug also exists here: http://llvm.org/bugs/show_bug.cgi?id=10521 , however the implementor points to violation.

Follow-up for Googlers:

The problem was indeed a Boost bug. This changeset 77289 should fix the issue for Boost 1.50. The corresponding Bug in Clang was marked invalid.

回答1:

The code in foreign_ptr.hpp is a redeclaration (if shared_ptr has already been defined), and as such not likely to cause problems (adding declarations to std is technically undefined behavior, but most compilers don't care since they don't really distinguish between standard library headers and other files). So the error can only be caused by shared_ptr being actually undefined.

Now libc++ obviously has a definition shared_ptr, so I can only suspect some C++03 library made it to the include path somehow and got preferred over libc++.