Workaround for py::dict() constructor on MSVC

MSVC fails to compile if the constructor is defined out-of-line.
The error states that it cannot deduce the type of the default template
parameter which is used for SFINAE.
This commit is contained in:
Dean Moldovan 2016-09-04 21:30:08 +02:00
parent 16db1bfbd7
commit 56e86ed094
3 changed files with 15 additions and 6 deletions

View File

@ -1134,10 +1134,6 @@ template <return_value_policy policy,
return operator()<policy>(std::forward<Args>(args)...);
}
template <typename... Args, typename /*SFINAE*/>
dict::dict(Args &&...args)
: dict(detail::unpacking_collector<>(std::forward<Args>(args)...).kwargs()) { }
#define PYBIND11_MAKE_OPAQUE(Type) \
namespace pybind11 { namespace detail { \
template<> class type_caster<Type> : public type_caster_base<Type> { }; \

View File

@ -358,6 +358,10 @@ template <template<typename> class P, typename T, typename... Ts>
struct any_of_t<P, T, Ts...> : conditional_t<P<T>::value, std::true_type, any_of_t<P, Ts...>> { };
#endif
/// Defer the evaluation of type T until types Us are instantiated
template <typename T, typename... /*Us*/> struct deferred_type { using type = T; };
template <typename T, typename... Us> using deferred_t = typename deferred_type<T, Us...>::type;
/// Ignore that a variable is unused in compiler warnings
inline void ignore_unused(const int *) { }

View File

@ -259,6 +259,12 @@ template <typename T> using is_keyword_or_ds = bool_constant<
is_keyword<T>::value || is_ds_unpacking<T>::value
>;
// Call argument collector forward declarations
template <return_value_policy policy = return_value_policy::automatic_reference>
class simple_collector;
template <return_value_policy policy = return_value_policy::automatic_reference>
class unpacking_collector;
NAMESPACE_END(detail)
#define PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, CvtStmt) \
@ -588,8 +594,11 @@ public:
if (!m_ptr) pybind11_fail("Could not allocate dict object!");
}
template <typename... Args,
typename = detail::enable_if_t<detail::all_of_t<detail::is_keyword_or_ds, Args...>::value>>
dict(Args &&...args);
typename = detail::enable_if_t<detail::all_of_t<detail::is_keyword_or_ds, Args...>::value>,
// MSVC workaround: it can't compile an out-of-line definition, so defer the collector
typename collector = detail::deferred_t<detail::unpacking_collector<>, Args...>>
dict(Args &&...args) : dict(collector(std::forward<Args>(args)...).kwargs()) { }
size_t size() const { return (size_t) PyDict_Size(m_ptr); }
detail::dict_iterator begin() const { return (++detail::dict_iterator(*this, 0)); }
detail::dict_iterator end() const { return detail::dict_iterator(); }