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

H

huili80

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);
}
 
H

huili80

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)


I tried the following slightly shorter code, but got the same error.
--------------------------------
template < typename T > T& obj();

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

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

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

int main()
{
f<X>(0);
}
 
H

huili80

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){}

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

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

int main()
{
f<X>(0);
}
 
H

huili80

The purpose was to test at compline time whether a class has a memfun that doesn't take any args.
 
A

Alf P. Steinbach

* (e-mail address removed):
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
};
};



- Alf
 
H

huili80

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(...){}

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

int main()
{
f<X>(0);
}
 
A

Alf P. Steinbach

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(...){}


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

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


Cheers & hth.,

- Alf
 
A

Alf P. Steinbach

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;
}


Cheers & hth.,

- Alf
 
H

huili80

Yes, explicitly checking against the function signature works, however I also want types like this to pass the test (this is why i have to use the type of a function call).

struct W
{

};
 
H

huili80

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){}
};
 
A

Alf P. Steinbach

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){}

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

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

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

If possible, upgrade the compiler.

g++ 4.3 is pretty old.

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


Cheers & hth.,

- Alf
 
H

huili80

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...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top