Clang has better error messages

Comparing the error messages created by Clang and by MSVC.

Consider this code:

#include <memory>

struct SPDeleter
{
    void operator()(int) const {}
};

int main()
{
    using T = int;
    std::shared_ptr<T> X( new T(), SPDeleter() );
}

The problem here is that that operator()() on the SPDeleter should take an int* not just an int.

MSVC gives this error message:

error C2661: 'std::shared_ptr<T>::shared_ptr': no overloaded function takes 2 arguments

which is misleading at best. The constructor of std::shared_ptr does have functions which take two arguments.

Compiling with clang gives a much better error message:

error: no matching constructor for initialization of 'std::shared_ptr<T>' (aka 'shared_ptr<int>')
    std::shared_ptr<T> X( new T(), SPDeleter() );

plus clang lists all the possible matches and explains why they were not chosen:

C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\memory:1526:5: note:
      candidate template ignored: requirement 'conjunction_v<std::is_move_constructible<SPDeleter>,
      std::_Can_call_function_object<SPDeleter &, int *&, void>, std::_SP_convertible<int, int>>' was not satisfied
      [with _Ux = int, _Dx = SPDeleter]
    shared_ptr(_Ux* _Px, _Dx _Dt) { // construct with _Px, deleter
    ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\memory:1540:5: note:
      candidate template ignored: requirement 'conjunction_v<std::is_move_constructible<SPDeleter>,
      std::_Can_call_function_object<SPDeleter &, nullptr_t &, void>>' was not satisfied [with _Dx = SPDeleter]
    shared_ptr(nullptr_t, _Dx _Dt) { // construct with nullptr, deleter
    ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\memory:1551:5: note:
      candidate template ignored: could not match 'shared_ptr<type-parameter-0-0>' against 'int *'
    shared_ptr(const shared_ptr<_Ty2>& _Right, element_type* _Px) noexcept {
    ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\memory:1557:5: note:
      candidate template ignored: could not match 'shared_ptr<type-parameter-0-0>' against 'int *'
    shared_ptr(shared_ptr<_Ty2>&& _Right, element_type* _Px) noexcept {
    ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\memory:1506:15: note:
      candidate constructor not viable: requires 1 argument, but 2 were provided
    constexpr shared_ptr(nullptr_t) noexcept {} // construct empty shared_ptr
              ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\memory:1512:14: note:
      candidate constructor template not viable: requires single argument '_Px', but 2 arguments were provided
    explicit shared_ptr(_Ux* _Px) { // construct shared_ptr object that owns _Px
             ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\memory:1562:5: note:
      candidate constructor not viable: requires single argument '_Other', but 2 arguments were provided
    shared_ptr(const shared_ptr& _Other) noexcept { // construct shared_ptr object that owns same resource as _Other
    ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\memory:1567:5: note:
      candidate constructor template not viable: requires single argument '_Other', but 2 arguments were provided
    shared_ptr(const shared_ptr<_Ty2>& _Other) noexcept {
    ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\memory:1572:5: note:
      candidate constructor not viable: requires single argument '_Right', but 2 arguments were provided
    shared_ptr(shared_ptr&& _Right) noexcept { // construct shared_ptr object that takes resource from _Right
    ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\memory:1577:5: note:
      candidate constructor template not viable: requires single argument '_Right', but 2 arguments were provided
    shared_ptr(shared_ptr<_Ty2>&& _Right) noexcept { // construct shared_ptr object that takes resource from _Right
    ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\memory:1582:14: note:
      candidate constructor template not viable: requires single argument '_Other', but 2 arguments were provided
    explicit shared_ptr(const weak_ptr<_Ty2>& _Other) { // construct shared_ptr object that owns resource *_Other
             ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\memory:1590:5: note:
      candidate constructor template not viable: requires single argument '_Other', but 2 arguments were provided
    shared_ptr(auto_ptr<_Ty2>&& _Other) { // construct shared_ptr object that owns *_Other.get()
    ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\memory:1601:5: note:
      candidate constructor template not viable: requires single argument '_Other', but 2 arguments were provided
    shared_ptr(unique_ptr<_Ux, _Dx>&& _Other) {
    ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\memory:1534:5: note:
      candidate constructor template not viable: requires 3 arguments, but 2 were provided
    shared_ptr(_Ux* _Px, _Dx _Dt, _Alloc _Ax) { // construct with _Px, deleter, allocator
    ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\memory:1546:5: note:
      candidate constructor template not viable: requires 3 arguments, but 2 were provided
    shared_ptr(nullptr_t, _Dx _Dt, _Alloc _Ax) { // construct with nullptr, deleter, allocator
    ^
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\memory:1504:15: note:
      candidate constructor not viable: requires 0 arguments, but 2 were provided
    constexpr shared_ptr() noexcept = default;