简体   繁体   中英

Why SFINAE doesn't work in this simple member function overloading

Why SFINAE doesn't work in this simple example? If I comment out the templated 'add' the code compiles ok. Why compiler doesn't try to call non-template 'add' after the substitution failure?

I'm using MSVS 2017.


#include <set>
#include <memory>

struct button_t
{
    virtual ~button_t() {}
};

struct up_down_button_t : button_t
{
};


struct gui_t
{

    std::set<std::shared_ptr<button_t> > buttons;

    void add(const std::shared_ptr<button_t>& b) {
        buttons.insert(b);
    }

    template<class container_t>
    void add(container_t& c) {
        for (auto& i : c)
            add(i);
    }

} gui;

int main(int argc, char* argv[]) {


    auto b = std::make_shared<up_down_button_t>();
    gui.add(b);

}

Is it possible to make that code work without verbose boilerplate code such as std::enable_if etc?

From cppreference :

Only the failures in the types and expressions in the immediate context of the function type or its template parameter types [or its explicit specifier (since C++20)] are SFINAE errors

Here, the failure happen in the body of the function, so it is a substitution failure, but not in SFINAE context - so it is an error.

Concepts are intended to help making this less boilerplate heavy, so you could try using them if your compiler support them already.

If you change your first function to:

template <class ptr_t>
void add(std::shared_ptr<ptr_t>& b) {
    buttons.insert(b);
}

Then your code will compile and works as expected.

Two things to notice:

  • Both functions are template .
  • Both take a reference to non const object.

A valid template function would be preferred to a non template function that need some "conversion".

By the way, there is no SFINAE in your example. In fact, template<class container_t> void add(container_t& c) is an acceptable match.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM