Add syntax sugar for resolving overloaded functions (#541)

diff --git a/docs/classes.rst b/docs/classes.rst
index 3e8f2ee..8729776 100644
--- a/docs/classes.rst
+++ b/docs/classes.rst
@@ -104,6 +104,8 @@
     >>> print(p)
     <example.Pet named 'Molly'>
 
+.. [#f1] Stateless closures are those with an empty pair of brackets ``[]`` as the capture object.
+
 .. _properties:
 
 Instance and static fields
@@ -337,6 +339,35 @@
      |
      |      Set the pet's name
 
+If you have a C++14 compatible compiler [#cpp14]_, you can use an alternative
+syntax to cast the overloaded function:
+
+.. code-block:: cpp
+
+    py::class_<Pet>(m, "Pet")
+        .def("set", py::overload_cast<int>(&Pet::set), "Set the pet's age")
+        .def("set", py::overload_cast<const std::string &>(&Pet::set), "Set the pet's name");
+
+Here, ``py::overload_cast`` only requires the parameter types to be specified.
+The return type and class are deduced. This avoids the additional noise of
+``void (Pet::*)()`` as seen in the raw cast. If a function is overloaded based
+on constness, the ``py::const_`` tag should be used:
+
+.. code-block:: cpp
+
+    struct Widget {
+        int foo(int x, float y);
+        int foo(int x, float y) const;
+    };
+
+    py::class_<Widget>(m, "Widget")
+       .def("foo_mutable", py::overload_cast<int, float>(&Widget::foo))
+       .def("foo_const",   py::overload_cast<int, float>(&Widget::foo, py::const_));
+
+
+.. [#cpp14] A compiler which supports the ``-std=c++14`` flag
+            or Visual Studio 2015 Update 2 and newer.
+
 .. note::
 
     To define multiple overloaded constructors, simply declare one after the
@@ -406,5 +437,3 @@
            ...
 
     By default, these are omitted to conserve space.
-
-.. [#f1] Stateless closures are those with an empty pair of brackets ``[]`` as the capture object.
diff --git a/include/pybind11/common.h b/include/pybind11/common.h
index 72e8e33..712c1a5 100644
--- a/include/pybind11/common.h
+++ b/include/pybind11/common.h
@@ -557,4 +557,39 @@
 /// Dummy destructor wrapper that can be used to expose classes with a private destructor
 struct nodelete { template <typename T> void operator()(T*) { } };
 
+// overload_cast requires variable templates: C++14 or MSVC 2015 Update 2
+#if defined(PYBIND11_CPP14) || _MSC_FULL_VER >= 190023918
+#define PYBIND11_OVERLOAD_CAST 1
+
+NAMESPACE_BEGIN(detail)
+template <typename... Args>
+struct overload_cast_impl {
+    template <typename Return>
+    constexpr auto operator()(Return (*pf)(Args...)) const noexcept
+                              -> decltype(pf) { return pf; }
+
+    template <typename Return, typename Class>
+    constexpr auto operator()(Return (Class::*pmf)(Args...), std::false_type = {}) const noexcept
+                              -> decltype(pmf) { return pmf; }
+
+    template <typename Return, typename Class>
+    constexpr auto operator()(Return (Class::*pmf)(Args...) const, std::true_type) const noexcept
+                              -> decltype(pmf) { return pmf; }
+};
+NAMESPACE_END(detail)
+
+/// Syntax sugar for resolving overloaded function pointers:
+///  - regular: static_cast<Return (Class::*)(Arg0, Arg1, Arg2)>(&Class::func)
+///  - sweet:   overload_cast<Arg0, Arg1, Arg2>(&Class::func)
+template <typename... Args>
+static constexpr detail::overload_cast_impl<Args...> overload_cast = {};
+// MSVC 2015 only accepts this particular initialization syntax for this variable template.
+
+/// Const member function selector for overload_cast
+///  - regular: static_cast<Return (Class::*)(Arg) const>(&Class::func)
+///  - sweet:   overload_cast<Arg>(&Class::func, const_)
+static constexpr auto const_ = std::true_type{};
+
+#endif // overload_cast
+
 NAMESPACE_END(pybind11)
diff --git a/tests/test_constants_and_functions.cpp b/tests/test_constants_and_functions.cpp
index 29a2796..c8c0392 100644
--- a/tests/test_constants_and_functions.cpp
+++ b/tests/test_constants_and_functions.cpp
@@ -23,6 +23,9 @@
     return "test_function(" + std::to_string(i) + ")";
 }
 
+py::str test_function4(int, float) { return "test_function(int, float)"; }
+py::str test_function4(float, int) { return "test_function(float, int)"; }
+
 py::bytes return_bytes() {
     const char *data = "\x01\x00\x02\x00";
     return std::string(data, 4);
@@ -45,6 +48,14 @@
     m.def("test_function", &test_function2);
     m.def("test_function", &test_function3);
 
+#if defined(PYBIND11_OVERLOAD_CAST)
+    m.def("test_function", py::overload_cast<int, float>(&test_function4));
+    m.def("test_function", py::overload_cast<float, int>(&test_function4));
+#else
+    m.def("test_function", static_cast<py::str (*)(int, float)>(&test_function4));
+    m.def("test_function", static_cast<py::str (*)(float, int)>(&test_function4));
+#endif
+
     py::enum_<MyEnum>(m, "MyEnum")
         .value("EFirstEntry", EFirstEntry)
         .value("ESecondEntry", ESecondEntry)
diff --git a/tests/test_constants_and_functions.py b/tests/test_constants_and_functions.py
index 2c6321e..d13d3af 100644
--- a/tests/test_constants_and_functions.py
+++ b/tests/test_constants_and_functions.py
@@ -14,6 +14,9 @@
     assert test_function(MyEnum.EFirstEntry) == "test_function(enum=1)"
     assert test_function(MyEnum.ESecondEntry) == "test_function(enum=2)"
 
+    assert test_function(1, 1.0) == "test_function(int, float)"
+    assert test_function(2.0, 2) == "test_function(float, int)"
+
 
 def test_bytes():
     from pybind11_tests import return_bytes, print_bytes
diff --git a/tests/test_methods_and_attributes.cpp b/tests/test_methods_and_attributes.cpp
index ab59d8c..11fc900 100644
--- a/tests/test_methods_and_attributes.cpp
+++ b/tests/test_methods_and_attributes.cpp
@@ -50,6 +50,11 @@
     int *internal4() { return &value; }                           // return by pointer
     const int *internal5() { return &value; }                     // return by const pointer
 
+    py::str overloaded(int, float) { return "(int, float)"; }
+    py::str overloaded(float, int) { return "(float, int)"; }
+    py::str overloaded(int, float) const { return "(int, float) const"; }
+    py::str overloaded(float, int) const { return "(float, int) const"; }
+
     int value = 0;
 };
 
@@ -117,6 +122,17 @@
         .def("internal3", &ExampleMandA::internal3)
         .def("internal4", &ExampleMandA::internal4)
         .def("internal5", &ExampleMandA::internal5)
+#if defined(PYBIND11_OVERLOAD_CAST)
+        .def("overloaded", py::overload_cast<int, float>(&ExampleMandA::overloaded))
+        .def("overloaded", py::overload_cast<float, int>(&ExampleMandA::overloaded))
+        .def("overloaded_const", py::overload_cast<int, float>(&ExampleMandA::overloaded, py::const_))
+        .def("overloaded_const", py::overload_cast<float, int>(&ExampleMandA::overloaded, py::const_))
+#else
+        .def("overloaded", static_cast<py::str (ExampleMandA::*)(int, float)>(&ExampleMandA::overloaded))
+        .def("overloaded", static_cast<py::str (ExampleMandA::*)(float, int)>(&ExampleMandA::overloaded))
+        .def("overloaded_const", static_cast<py::str (ExampleMandA::*)(int, float) const>(&ExampleMandA::overloaded))
+        .def("overloaded_const", static_cast<py::str (ExampleMandA::*)(float, int) const>(&ExampleMandA::overloaded))
+#endif
         .def("__str__", &ExampleMandA::toString)
         .def_readwrite("value", &ExampleMandA::value)
         ;
diff --git a/tests/test_methods_and_attributes.py b/tests/test_methods_and_attributes.py
index 28c0de5..2b0f8d5 100644
--- a/tests/test_methods_and_attributes.py
+++ b/tests/test_methods_and_attributes.py
@@ -31,6 +31,11 @@
     assert instance1.internal4() == 320
     assert instance1.internal5() == 320
 
+    assert instance1.overloaded(1, 1.0) == "(int, float)"
+    assert instance1.overloaded(2.0, 2) == "(float, int)"
+    assert instance1.overloaded_const(3, 3.0) == "(int, float) const"
+    assert instance1.overloaded_const(4.0, 4) == "(float, int) const"
+
     assert instance1.value == 320
     instance1.value = 100
     assert str(instance1) == "ExampleMandA[value=100]"