Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Repost: Does anyone have a workaround for this gcc4.3 issue?

62 views
Skip to first unread message

hui...@gmail.com

unread,
Dec 15, 2013, 5:24:39 PM12/15/13
to
The code attached compiles with gcc4.8 and above, however, gcc4.3 fails to compile, and i hope to find a workaround for gcc4.3 since that's currently the only compiler available to me (at work, that is).

The non-compile appears to be a gcc4.3 issue (bug maybe?), where a substitution failure, i.e., the instantiation of test<X> when calling f<X>(0), is mistakenly being treated as an error.

As for the code itself, since i'm using gcc4.3 which doesn't have c++11, therefore no decltype, so i had to use the gcc extension typeof, which is really the only thing non-standard about it.

I'd very much appreciate any help. Thanks!

code here:
-------------------------------
template < typename T > T& obj();

template < typename T, typename=typeof(obj<T>().memfun()) >
struct test {};

template < typename T > test<T> f(int){}

template <typename> char f(...){}

struct X
{
void memfun(int){};
};

int main()
{
f<X>(0);
}
Message has been deleted

hui...@gmail.com

unread,
Dec 15, 2013, 5:46:40 PM12/15/13
to
The error i got from gcc4.3 is:
test.cpp: In function 'int main()':
test.cpp:14: error: no matching function for call to 'X::memfun()'
test.cpp:9: note: candidates are: void X::memfun(int)


I tried a slightly shorter version, with the hope to generate a template function substitution failure rather than a template class substitution failure, but i got the same error.
--------------------
template < typename T > T& obj();

template < typename T > typeof(obj<T>().memfun()) f(int){}

Alf P. Steinbach

unread,
Dec 16, 2013, 12:03:40 AM12/16/13
to
On 15.12.2013 23:44, hui...@gmail.com wrote:
> The compile error given by gcc4.3 is:
> mbpro:~ huil$ g++-mp-4.3 test.cpp
> test.cpp: In function 'int main()':
> test.cpp:17: error: no matching function for call to 'X::memfun()'
> test.cpp:12: note: candidates are: void X::memfun(int)

Have you tried the obvious, namely providing an argument in the call of
the the function that requires an argument?


Cheers,

- Alf


hui...@gmail.com

unread,
Dec 16, 2013, 7:41:43 AM12/16/13
to
The purpose was to test at compline time whether a class has a memfun that doesn't take any args.

Alf P. Steinbach

unread,
Dec 16, 2013, 8:08:20 AM12/16/13
to
* hui...@gmail.com:
> The purpose was to test at compline time whether a class has a memfun that
> doesn't take any args.

The following code may help, or not. You'd have to adapt it both for
basic purpose and to old compiler. Anyway, the idea is to have the
SFINAE expression in the function return type, instead of in the default
for a template arg.


[code]
template< class Type >
class Use_custom_sizefunc_
{
private:
template< class U >
static auto the_type_for( U& u ) -> decltype( u.size() );

static auto the_type_for( ... ) -> void;

public:
typedef decltype( the_type_for( declval<Type const&>() ) )
Size_func_result;
enum { yes =
numeric_limits< Size_func_result >::is_integer &&
!is_same<Size_func_result, bool>::value
};
};
[/code]



- Alf

hui...@gmail.com

unread,
Dec 16, 2013, 8:30:11 AM12/16/13
to
I think i tried something similar (posted in an earlier post, but here is the code again). it didn't work with gcc4.3.
-------------------
template < typename T > T& obj();

template < typename T > typeof(obj<T>().memfun()) f(int){}

Alf P. Steinbach

unread,
Dec 16, 2013, 9:12:02 AM12/16/13
to
On 16.12.2013 14:30, hui...@gmail.com wrote:
> I think i tried something similar (posted in an earlier post, but here is the code again). it didn't work with gcc4.3.
> -------------------
> template < typename T > T& obj();
>
> template < typename T > typeof(obj<T>().memfun()) f(int){}
>
> template <typename> char f(...){}

Try removing "template<typename>" here.


>
> struct X
> {
> void memfun(int){};
> };
>
> int main()
> {
> f<X>(0);
> }


Cheers & hth.,

- Alf


hui...@gmail.com

unread,
Dec 16, 2013, 9:15:19 AM12/16/13
to
i don't understand how that could help...

On Monday, December 16, 2013 9:12:02 AM UTC-5, Alf P. Steinbach wrote:

Alf P. Steinbach

unread,
Dec 16, 2013, 11:22:27 AM12/16/13
to
On 16.12.2013 15:15, hui...@gmail.com wrote:
> i don't understand how that could help...

Sorry, I don't what I was (not) thinking. :-)

Your latest code does compile with g++ 4.4, and fails with g++ 3.3.

If it doesn't compile with g++ 4.3, then the original on which I based
the following, reportedly compiles with g++ 4.1, so should be fine?

[code]
struct Yes { char x; };
struct No { char x[2*sizeof(Yes)]; };

// This type won't compile if the second template parameter isn't of type T,
// so I can put a function pointer type in the first parameter and the
function
// itself in the second thus checking that the function has a specific
signature.
template <typename T, T> struct Type_check;

// Baed on FireAphi's code at <url:
http://stackoverflow.com/a/3627243/464581>.
template <class Type>
class Has_memfun
{
// A helper struct to hold the declaration of the function pointer.
// Change it if the function signature changes.
template <typename T> struct Func_type
{
typedef void (T::*fptr)();
};

template <typename T> static Yes has_memfun(Type_check< typename
Func_type<T>::fptr, &T::memfun >*);
template <typename T> static No has_memfun(...);

public:
static bool const yes = (sizeof(has_memfun<Type>(0)) == sizeof(Yes));
};

struct X
{ void memfun(int){}; };

struct Y
{};

struct Z
{ void memfun(){}; };


#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
bool const x_has = Has_memfun<X>::yes;
bool const y_has = Has_memfun<Y>::yes;
bool const z_has = Has_memfun<Z>::yes;

cout << (x_has? "X has memfun(), yay!" : "No X::memfun()") << endl;
cout << (y_has? "Y has memfun(), yay!" : "No Y::memfun()") << endl;
cout << (z_has? "Z has memfun(), yay!" : "No Z::memfun()") << endl;
}
[/code]
Message has been deleted

hui...@gmail.com

unread,
Dec 16, 2013, 12:39:45 PM12/16/13
to
Yes, explicitly checking against the function signature works, however I also want types like this (see code below) to pass the test. that's why i have to use the type of a function call, and can't just use a signature check.

struct W
{
void memfun(int=0){}
};

Alf P. Steinbach

unread,
Dec 17, 2013, 12:09:45 AM12/17/13
to
If possible, upgrade the compiler.

g++ 4.3 is pretty old.

Even g++ 4.4 doesn't seem to have these problems.

hui...@gmail.com

unread,
Dec 17, 2013, 2:16:36 AM12/17/13
to
Yeah I guess maybe there is no workaround for gcc4.3 for this particular issue... I'm getting gcc4.8 at work hopefully in a few months, guess I'm just gonna have to wait...
0 new messages