Implicit conversions with std::function [duplicate]

佐手、 提交于 2020-02-26 09:44:07

问题


Possible Duplicates:
Why can't my C++ compiler deduce template argument for boost function?
Isn't the template argument (the signature) of std::function part of its type?

I have the following:

#include <functional>

void Foo( std::function<void()>    );
void Foo( std::function<void(int)> );
void Bar();

int main()
{
  Foo( Bar );     // Error: ambiguous
  Foo( [](){} );  // Error: ambiguous

  Foo( std::function<void()>( Bar    ) ); // Ok
  Foo( std::function<void()>( [](){} ) ); // Ok
}

Can I make the first two lines in main() work without the function-style cast in the last two lines? Perhaps with a std::enable_if solution?


回答1:


Any call to Foo with a parameter which is not exactly one of std::function<void()> and std::function<void(int)> will result in an unresolved overloading. Even silly things like Foo(1) or Foo("abc"). This is because constructors of std::function are templated and accept any type. std::function<void()>(1) would fail at instantiation, but overload resolution happens before instantiation.

So no, you need to provide an exact match to one of the functions, one way or another. You may introduce other overloaded instances of Foo, like

void Foo(void (*)());
void Foo(void (*)(int));

and this will result in a better match and the ambiguity will be no more.




回答2:


It is possible to use SFINAE to make this work correctly, in C++0x. However, MSVC's SFINAE bugs make it impossible for them, as far as I know, and GCC's library implementers don't seem to have noticed, so this unfortunately doesn't work.

You could also try some sort of make_function, I guess. Excuse my variadic templates, it's been a while.

template<typename T> struct function_proxy {
    T f;
    template<typename Ret, typename... T> operator std::enable_if<std::is_same<Ret, decltype(f(std::declval<T>()...))>::value, std::function<Ret(T...)>>::type () {
        return std::function<Ret(T...)>(f);
    }
};
template<typename T> function_proxy<T> make_function(T&& t) {
    return function_proxy { std::forward<T>(t); }
}


来源:https://stackoverflow.com/questions/6193734/implicit-conversions-with-stdfunction

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!