diff --git a/docs/basics.rst b/docs/basics.rst index 73d217072..1f40f198d 100644 --- a/docs/basics.rst +++ b/docs/basics.rst @@ -177,6 +177,21 @@ The keyword names also appear in the function signatures within the documentatio A function which adds two numbers +A shorter notation for named arguments is also available: + +.. code-block:: cpp + + // regular notation + m.def("add1", &add, py::arg("i"), py::arg("j")); + // shorthand + using namespace pybind11::literals; + m.def("add2", &add, "i"_a, "j"_a); + +The :var:`_a` suffix forms a C++11 literal which is equivalent to :class:`arg`. +Note that the literal operator must first be made visible with the directive +``using namespace pybind11::literals``. This does not bring in anything else +from the ``pybind11`` namespace except for literals. + .. _default_args: Default arguments @@ -213,6 +228,15 @@ The default values also appear within the documentation. A function which adds two numbers +The shorthand notation is also available for default arguments: + +.. code-block:: cpp + + // regular notation + m.def("add1", &add, py::arg("i") = 1, py::arg("j") = 2); + // shorthand + m.def("add2", &add, "i"_a=1, "j"_a=2); + .. _supported_types: Supported data types @@ -283,4 +307,3 @@ as arguments and return values, refer to the section on binding :ref:`classes`. .. [#f1] In practice, implementation and binding code will generally be located in separate files. - diff --git a/example/example11.cpp b/example/example11.cpp index 799fa6226..636a36ce1 100644 --- a/example/example11.cpp +++ b/example/example11.cpp @@ -55,4 +55,7 @@ void init_ex11(py::module &m) { m.def("args_function", &args_function); m.def("args_kwargs_function", &args_kwargs_function); + + using namespace py::literals; + m.def("kw_func_udl", &kw_func, "x"_a, "y"_a=300); } diff --git a/example/example11.py b/example/example11.py index ff35be2e4..33ed80be3 100755 --- a/example/example11.py +++ b/example/example11.py @@ -6,12 +6,13 @@ import pydoc sys.path.append('.') from example import kw_func, kw_func2, kw_func3, kw_func4, call_kw_func -from example import args_function, args_kwargs_function +from example import args_function, args_kwargs_function, kw_func_udl print(pydoc.render_doc(kw_func, "Help on %s")) print(pydoc.render_doc(kw_func2, "Help on %s")) print(pydoc.render_doc(kw_func3, "Help on %s")) print(pydoc.render_doc(kw_func4, "Help on %s")) +print(pydoc.render_doc(kw_func_udl, "Help on %s")) kw_func(5, 10) kw_func(5, y=10) @@ -39,3 +40,5 @@ call_kw_func(kw_func2) args_function('arg1_value', 'arg2_value', 3) args_kwargs_function('arg1_value', 'arg2_value', arg3='arg3_value', arg4=4) + +kw_func_udl(x=5, y=10) diff --git a/example/example11.ref b/example/example11.ref index f4c23aecd..e965187ea 100644 --- a/example/example11.ref +++ b/example/example11.ref @@ -18,6 +18,11 @@ Help on built-in function kw_func4 in module example kkww__ffuunncc44(...) kw_func4(myList : list = [13L, 17L]) -> NoneType +Help on built-in function kw_func_udl in module example + +kkww__ffuunncc__uuddll(...) + kw_func_udl(x : int, y : int = 300L) -> NoneType + kw_func(x=5, y=10) kw_func(x=5, y=10) kw_func(x=5, y=10) @@ -40,3 +45,5 @@ got argument: arg1_value got argument: arg2_value got keyword argument: arg3 -> arg3_value got keyword argument: arg4 -> 4 + +kw_func(x=5, y=10) diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h index 5e2d8f2e0..d2525e5fc 100644 --- a/include/pybind11/attr.h +++ b/include/pybind11/attr.h @@ -18,23 +18,29 @@ template struct arg_t; /// Annotation for keyword arguments struct arg { - arg(const char *name) : name(name) { } - template arg_t operator=(const T &value); - template arg_t operator=(T const (&value)[N]); + constexpr arg(const char *name) : name(name) { } + + template + constexpr arg_t operator=(const T &value) const { return {name, value}; } + template + constexpr arg_t operator=(T const (&value)[N]) const { + return operator=((const T *) value); + }; + const char *name; }; /// Annotation for keyword arguments with default values template struct arg_t : public arg { - arg_t(const char *name, const T &value, const char *descr = nullptr) + constexpr arg_t(const char *name, const T &value, const char *descr = nullptr) : arg(name), value(value), descr(descr) { } T value; const char *descr; }; -template arg_t arg::operator=(const T &value) { return arg_t(name, value); } -template arg_t arg::operator=(T const (&value)[N]) { - return operator=((const T *) value); +inline namespace literals { +/// String literal version of arg +constexpr arg operator"" _a(const char *name, size_t) { return {name}; } } /// Annotation for methods