Allow using Bind() with non-public inheritance in C++11 code
Using Bind() with a method of the class deriving from wxEvtHandler non-publicly used to result in a compile-time error, but at least with C++11 we can detect this case and allow the code to compile. Closes #17623.
This commit is contained in:
@@ -79,6 +79,8 @@ All:
|
||||
- Handle strings with embedded NULs in wxDataStream (Nitch).
|
||||
- Don't crash in wxTextFile::GetLastLine() if the file is empty (crohr).
|
||||
- Add wxString::cbegin() and cend() method (Lauri Nurmi).
|
||||
- Allow using Bind() with event handlers non-publicly deriving from
|
||||
wxEvtHandler and/or wxTrackable in C++11 code (Raul Tambre, mmarsan).
|
||||
|
||||
All (GUI):
|
||||
|
||||
|
@@ -332,7 +332,7 @@ class wxEventFunctorMethod
|
||||
<
|
||||
Class,
|
||||
EventArg,
|
||||
wxConvertibleTo<Class, wxEvtHandler>::value != 0
|
||||
wxIsPubliclyDerived<Class, wxEvtHandler>::value != 0
|
||||
>
|
||||
{
|
||||
private:
|
||||
|
@@ -34,5 +34,27 @@ struct wxConvertibleTo
|
||||
};
|
||||
};
|
||||
|
||||
// This is similar to wxConvertibleTo, except that when using a C++11 compiler,
|
||||
// the case of D deriving from B non-publicly will be detected and the correct
|
||||
// value (false) will be deduced instead of getting a compile-time error as
|
||||
// with wxConvertibleTo. For pre-C++11 compilers there is no difference between
|
||||
// this helper and wxConvertibleTo.
|
||||
template <class D, class B>
|
||||
struct wxIsPubliclyDerived
|
||||
{
|
||||
enum
|
||||
{
|
||||
#if __cplusplus >= 201103 || (defined(_MSC_VER) && _MSC_VER >= 1600)
|
||||
// If C++11 is available we use this, as on most compilers it's a
|
||||
// built-in and will be evaluated at compile-time.
|
||||
value = std::is_base_of<B, D>::value && std::is_convertible<D*, B*>::value
|
||||
#else
|
||||
// When not using C++11, we fall back to wxConvertibleTo, which fails
|
||||
// at compile-time if D doesn't publicly derive from B.
|
||||
value = wxConvertibleTo<D, B>::value
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
#endif // _WX_META_CONVERTIBLE_H_
|
||||
|
||||
|
@@ -19,7 +19,7 @@
|
||||
template <class T>
|
||||
struct wxIsStaticTrackable
|
||||
{
|
||||
enum { value = wxConvertibleTo<T, wxTrackable>::value };
|
||||
enum { value = wxIsPubliclyDerived<T, wxTrackable>::value };
|
||||
};
|
||||
|
||||
|
||||
|
@@ -509,3 +509,21 @@ void EvtHandlerTestCase::UnbindFromHandler()
|
||||
|
||||
handler.ProcessEvent(e);
|
||||
}
|
||||
|
||||
// This is a compilation-time-only test: just check that a class inheriting
|
||||
// from wxEvtHandler non-publicly can use Bind() with its method, this used to
|
||||
// result in compilation errors.
|
||||
// Note that this test will work only on C++11 compilers, so we test this only
|
||||
// for such compilers.
|
||||
#if __cplusplus >= 201103
|
||||
class HandlerNonPublic : protected wxEvtHandler
|
||||
{
|
||||
public:
|
||||
HandlerNonPublic()
|
||||
{
|
||||
Bind(wxEVT_IDLE, &HandlerNonPublic::OnIdle, this);
|
||||
}
|
||||
|
||||
void OnIdle(wxIdleEvent&) { }
|
||||
};
|
||||
#endif // C++11
|
||||
|
Reference in New Issue
Block a user