Try this workaround:
. . .
if constexpr( false ) LT( ).unique( );
func_void_t f5 = <::unique;
. . .
or
. . .
using unused = decltype( std::declval<LT>( ).unique( ) );
func_void_t f5 = <::unique;
. . .
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
According to MSDN 'std::list::unique()' returns type void - so why doesn't the following C++ code compile in VS2019?
Can anyone see a problem with the code? Or suggests a fix / workaround?
#include <list>
using LT = std::list<int>;
using func_void_t = void(LT::*)();
using func_ref_t = LT::reference(LT::*)();
using func_iter_t = LT::iterator(LT::*)();
int main (int argc, char *argv[])
{
// Non-overloaded members
func_void_t f1 = <::reverse; // Succeeds
func_void_t f2 = <::clear; // Succeeds
func_void_t f3 = <::sort; // Succeeds
func_void_t f4 = <::pop_front; // Succeeds
// Members with overloads
func_ref_t f6 = <::front; // Succeeds
func_iter_t f7 = <::end; // Succeeds
func_void_t f5 = <::unique; // FAILS (error C2440)
return 0;
}
Try this workaround:
. . .
if constexpr( false ) LT( ).unique( );
func_void_t f5 = <::unique;
. . .
or
. . .
using unused = decltype( std::declval<LT>( ).unique( ) );
func_void_t f5 = <::unique;
. . .
Wow! I'd scratched my head for over a week with this but I tried your solution #2 and it seems to fix the problem - many thanks !!
It'd be really great if you could explain a bit how that solution works....
First, std::list::unique
returns void
in C++17 and earlier, but size_t
in C++20: source. Even if you get your program to compile now, it will likely start to break soon.
Second, it is generally not portable to take an address of a member function of a standard library class:
[member.functions]/2 For a non-virtual member function described in the C++ standard library, an implementation may declare a different set of member function signatures, provided that any call to the member function that would select an overload from the set of declarations described in this document behaves as if that overload were selected. [Note: For instance, an implementation may add parameters with default values, or replace a member function with default arguments with two or more member functions with equivalent behavior, or add additional signatures for a member function name. —end note]
So your whole design relies on implementation details.
What is the original problem you are trying to solve, for which you want to use pointers-to-member? There may be other, portable ways to solve it.
Many thanks guys - I appreciate all the help. There's quite a long discussion about this, over on CodeGuru
In a nutshell, I'm trying to build some code for a library we use here (the library's called Lua). It seems to produce a "customized" version of some general template stuff, like list and vector etc (i.e. it only allows some of the available functions - whereas some extra ones can be added)
In post #14, 2kaud (the guy who's been helping me) mentions that he'll be passing this on to the VS development team so hopefully they'll become aware of it soon.