sadaszewski / concaveman-cpp

C++ port of mapbox's JS concaveman, with a Python wrapper
BSD 2-Clause "Simplified" License
153 stars 41 forks source link

Compile error: Call to make_unique is ambiguous #3

Closed mpadge closed 5 years ago

mpadge commented 5 years ago

Great work translating this to C++ - thanks! It'd be even better if you could fix this:

cd src/main/cpp
clang++ concaveman.cpp -o object

produces the following:

In file included from concaveman.cpp:10:
./concaveman.h:202:22: error: call to 'make_unique' is ambiguous
            auto r = make_unique<type>(data, bounds);
                     ^~~~~~~~~~~~~~~~~
./concaveman.h:503:14: note: in instantiation of member function 'rtree<double, 2, 16, std::array<double, 2> >::insert' requested here
        tree.insert(p, { p[0], p[1], p[0], p[1] });
             ^
concaveman.cpp:51:27: note: in instantiation of function template specialization 'concaveman<double, 16>' requested here
    auto concave_points = concaveman<T, 16>(points, hull, concavity, lengthThreshold);
                          ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/unique_ptr.h:852:5: note: candidate function [with _Tp = rtree<double, 2, 16, std::array<double, 2> >, _Args = <std::array<double, 2> &, const std::array<double, 4> &>]
    make_unique(_Args&&... __args)
    ^
./concaveman.h:22:20: note: candidate function [with T = rtree<double, 2, 16, std::array<double, 2> >, Args = <std::array<double, 2> &, const std::array<double, 4> &>]
std::unique_ptr<T> make_unique(Args&&... args) {
                   ^
./concaveman.h:222:21: error: call to 'make_unique' is ambiguous
        auto leaf = make_unique<type>(best_child.get().data(),
                    ^~~~~~~~~~~~~~~~~
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/unique_ptr.h:852:5: note: candidate function [with _Tp = rtree<double, 2, 16, std::array<double, 2> >, _Args = <std::array<double, 2>, const std::array<double, 4> &>]
    make_unique(_Args&&... __args)
    ^
./concaveman.h:22:20: note: candidate function [with T = rtree<double, 2, 16, std::array<double, 2> >, Args = <std::array<double, 2>, const std::array<double, 4> &>]
std::unique_ptr<T> make_unique(Args&&... args) {
                   ^
./concaveman.h:202:22: error: call to 'make_unique' is ambiguous
            auto r = make_unique<type>(data, bounds);
                     ^~~~~~~~~~~~~~~~~
./concaveman.h:528:17: note: in instantiation of member function 'rtree<double, 2, 16, CircularElement<Node<double> > *>::insert' requested here
        segTree.insert(elem, { node.minX,
                ^
concaveman.cpp:51:27: note: in instantiation of function template specialization 'concaveman<double, 16>' requested here
    auto concave_points = concaveman<T, 16>(points, hull, concavity, lengthThreshold);
                          ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/unique_ptr.h:852:5: note: candidate function [with _Tp = rtree<double, 2, 16, CircularElement<Node<double> > *>, _Args = <CircularElement<Node<double> > *&, const std::array<double, 4> &>]
    make_unique(_Args&&... __args)
    ^
./concaveman.h:22:20: note: candidate function [with T = rtree<double, 2, 16, CircularElement<Node<double> > *>, Args = <CircularElement<Node<double> > *&, const std::array<double, 4> &>]
std::unique_ptr<T> make_unique(Args&&... args) {
                   ^
./concaveman.h:222:21: error: call to 'make_unique' is ambiguous
        auto leaf = make_unique<type>(best_child.get().data(),
                    ^~~~~~~~~~~~~~~~~
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/unique_ptr.h:852:5: note: candidate function [with _Tp = rtree<double, 2, 16, CircularElement<Node<double> > *>, _Args = <CircularElement<Node<double> > *, const std::array<double, 4> &>]
    make_unique(_Args&&... __args)
    ^
./concaveman.h:22:20: note: candidate function [with T = rtree<double, 2, 16, CircularElement<Node<double> > *>, Args = <CircularElement<Node<double> > *, const std::array<double, 4> &>]
std::unique_ptr<T> make_unique(Args&&... args) {
                   ^
4 errors generated.

That should be entirely reproducible. Thanks!

sadaszewski commented 5 years ago

Hi Mark,

Thanks for reporting this. The point is make_unique() was not standard in C++11 and that's the version this code is aiming at. My own implementation is not in std:: namespace so I am a bit confused as to why it would be ambiguous. Could it be that one of the headers or compile units has "using namespace std;" in it? Wouldn't this make std::make_unique() the preferred version though... Or could it be that your unique_ptr defines make_unique() in global namespace? I am a bit confused here. Anyhow, the easiest solution is to remove my definition of make_unique altogether if you are aiming for C++14 and above. Alternatively you could put it inside some sort of #ifdef. I am open to suggestions/patches/pull requests, etc.

Cheers,

-- Stanislaw

mpadge commented 5 years ago

Thanks for the quick response, and yes, it seems that you're right. There is no "using namespace std", but what you say otherwise makes sense. I'll have a play and hope to close myself asap. Cheers!

mpadge commented 5 years ago

Thanks @sadaszewski, simply enforcing -std=c++11 does the trick. It would likely be helpful for others is you make this need clear on your README.

ShenRen commented 4 years ago

the best way is putting your make_unique into a namespace , like not_std,