
Compiling this code with gcc: #include <boost/config.hpp> #include <boost/mpl/apply.hpp> template < class MF, class T > struct myMF : boost::mpl::apply<MF,T> { BOOST_STATIC_CONSTANT(bool,value=type::value); }; int main() { return 0; } Gives: "gcc.compile.c++ ..\..\..\bin.v2\libs\tti\test\TestMFHasTypeMFC.test\gcc-mingw-4.5.2\debug\TestMFHasTypeMFC.o TestMFHasTypeMFC.cpp:18:5: error: 'type' has not been declared "g++" -ftemplate-depth-128 -O0 -fno-inline -Wall -pedantic -g -Wno-variadic-macros -I"..\..\.." -I"C:\Programming\VersionControl\boost" -c -o "..\..\..\bin.v2\libs\tti\test\TestMFHasTypeMFC.test\gcc-mingw-4.5.2\debug\TestMFHasTypeMFC.o" "TestMFHasTypeMFC.cpp"" MF is a metafunction with a boost::mpl::bool_ type. Since I am using apply using metafunction forwarding, why does gcc tell me that 'type' has not been declared ? Is this a bug in gcc or in my simple code above ? The error occurs with all flavors of gcc, but VC++ 8,9,10 gives no error.

On 02/03/11 16:42, Edward Diener wrote:
#include <boost/config.hpp> #include <boost/mpl/apply.hpp>
template < class MF, class T > struct myMF : boost::mpl::apply<MF,T> { BOOST_STATIC_CONSTANT(bool,value=type::value); };
int main() { return 0; } clang complains also:
/home/evansl/download/llvm/svn/build/Debug+Asserts/bin/clang++ -c -std=c++0x -U__GXX_EXPERIMENTAL_CXX0X__ -I/home/evansl/prog_dev/boost-svn/ro/sandbox/rw/variadic_templates -I/home/evansl/prog_dev/boost-svn/ro/sandbox/ro/switch -I/home/evansl/prog_dev/boost-svn/ro/trunk -DTEMPLATE_DEPTH=300 myMF.cpp -MMD -o /home/evansl/prog_dev/boost-svn/ro/trunk/sandbox-local/build/clangxx/clang/myMF.o myMF.cpp:20:6: error: use of undeclared identifier 'type' BOOST_STATIC_CONSTANT(bool,value=type::value); ^ myMF.cpp:20:39: note: instantiated from: BOOST_STATIC_CONSTANT(bool,value=type::value); ^ 1 error generated. m

On 2/3/2011 2:42 PM, Edward Diener wrote:
Compiling this code with gcc:
#include <boost/config.hpp> #include <boost/mpl/apply.hpp>
template < class MF, class T
struct myMF : boost::mpl::apply<MF,T> { BOOST_STATIC_CONSTANT(bool,value=type::value);
AFAIK, since type resides in the base class, which is a dependent type, the compiler won't look in the base class for type; it's looking in namespace scope and there's no type at namespace scope. So you either need a using declaration or explicit qualification. (Some versions of MSVC, at least, happily but incorrectly accept the above code.) Sorry, no references handy :(
}; [...]
HTH, - Jeff

On 2/3/2011 5:58 PM, Jeffrey Lee Hellrung, Jr. wrote:
On 2/3/2011 2:42 PM, Edward Diener wrote:
Compiling this code with gcc:
#include <boost/config.hpp> #include <boost/mpl/apply.hpp>
template < class MF, class T
struct myMF : boost::mpl::apply<MF,T> { BOOST_STATIC_CONSTANT(bool,value=type::value);
AFAIK, since type resides in the base class, which is a dependent type, the compiler won't look in the base class for type; it's looking in namespace scope and there's no type at namespace scope. So you either need a using declaration or explicit qualification. (Some versions of MSVC, at least, happily but incorrectly accept the above code.)
Sorry, no references handy :(
You are correct. I should have realized this, but the MPL book suggestions metafunction forwarding so I used it.

AMDG On 2/3/2011 2:42 PM, Edward Diener wrote:
Compiling this code with gcc:
#include <boost/config.hpp> #include <boost/mpl/apply.hpp>
template < class MF, class T
struct myMF : boost::mpl::apply<MF,T> { BOOST_STATIC_CONSTANT(bool,value=type::value); };
int main() { return 0; }
Gives:
"gcc.compile.c++ ..\..\..\bin.v2\libs\tti\test\TestMFHasTypeMFC.test\gcc-mingw-4.5.2\debug\TestMFHasTypeMFC.o
TestMFHasTypeMFC.cpp:18:5: error: 'type' has not been declared
gcc is correct. Members of a dependent base class are not visible in the derived class. (This is necessary to allow the template to be parsed before the template arguments are known.). Add using typename boost::mpl::apply<MF,T>::type; In Christ, Steven Watanabe

On 02/03/11 17:02, Steven Watanabe wrote:
AMDG
On 2/3/2011 2:42 PM, Edward Diener wrote:
Compiling this code with gcc:
#include <boost/config.hpp> #include <boost/mpl/apply.hpp>
template < class MF, class T
struct myMF : boost::mpl::apply<MF,T> { BOOST_STATIC_CONSTANT(bool,value=type::value); };
int main() { return 0; }
Gives:
"gcc.compile.c++ ..\..\..\bin.v2\libs\tti\test\TestMFHasTypeMFC.test\gcc-mingw-4.5.2\debug\TestMFHasTypeMFC.o
TestMFHasTypeMFC.cpp:18:5: error: 'type' has not been declared
gcc is correct. Members of a dependent base class are not visible in the derived class. (This is necessary to allow the template to be parsed before the template arguments are known.).
Add using typename boost::mpl::apply<MF,T>::type;
In Christ, Steven Watanabe _______________________________________________ That using works with clang++; however, my gcc (gcc4.5.1) still doesn't like it:
make using cat myMF.cpp //Copied from post with headers: /* From: Edward Diener <eldiener@tropicsoft.com> Newsgroups: gmane.comp.lib.boost.devel Subject: [mpl] Using apply with gcc error Date: Thu, 03 Feb 2011 17:42:44 -0500 Lines: 47 */ #include <boost/config.hpp> #include <boost/mpl/apply.hpp> template < class MF, class T > struct myMF : boost::mpl::apply<MF,T> { using typename boost::mpl::apply<MF,T>::type; BOOST_STATIC_CONSTANT(bool,value=type::value); }; int main() { return 0; } /home/evansl/download/llvm/svn/build/Debug+Asserts/bin/clang++ -c -std=c++0x -U__GXX_EXPERIMENTAL_CXX0X__ -c myMF.cpp /home/evansl/download/gcc/4.5.1-release/install/bin/g++ -c -Wall -ftemplate-depth-300 -O0 -std=gnu++0x -c myMF.cpp myMF.cpp:21:6: error: 'type' is not a class, namespace, or enumeration make: [using] Error 1 (ignored) Compilation finished at Thu Feb 3 17:04:44

On 2/3/2011 6:08 PM, Larry Evans wrote:
On 02/03/11 17:02, Steven Watanabe wrote:
AMDG
On 2/3/2011 2:42 PM, Edward Diener wrote:
Compiling this code with gcc:
#include<boost/config.hpp> #include<boost/mpl/apply.hpp>
template < class MF, class T
struct myMF : boost::mpl::apply<MF,T> { BOOST_STATIC_CONSTANT(bool,value=type::value); };
int main() { return 0; }
Gives:
"gcc.compile.c++ ..\..\..\bin.v2\libs\tti\test\TestMFHasTypeMFC.test\gcc-mingw-4.5.2\debug\TestMFHasTypeMFC.o
TestMFHasTypeMFC.cpp:18:5: error: 'type' has not been declared
gcc is correct. Members of a dependent base class are not visible in the derived class. (This is necessary to allow the template to be parsed before the template arguments are known.).
Add using typename boost::mpl::apply<MF,T>::type;
In Christ, Steven Watanabe _______________________________________________ That using works with clang++; however, my gcc (gcc4.5.1) still doesn't like it:
make using cat myMF.cpp //Copied from post with headers: /* From: Edward Diener<eldiener@tropicsoft.com> Newsgroups: gmane.comp.lib.boost.devel Subject: [mpl] Using apply with gcc error Date: Thu, 03 Feb 2011 17:42:44 -0500 Lines: 47 */ #include<boost/config.hpp> #include<boost/mpl/apply.hpp>
template < class MF, class T > struct myMF : boost::mpl::apply<MF,T> { using typename boost::mpl::apply<MF,T>::type; BOOST_STATIC_CONSTANT(bool,value=type::value); };
int main() { return 0; } /home/evansl/download/llvm/svn/build/Debug+Asserts/bin/clang++ -c -std=c++0x -U__GXX_EXPERIMENTAL_CXX0X__ -c myMF.cpp /home/evansl/download/gcc/4.5.1-release/install/bin/g++ -c -Wall -ftemplate-depth-300 -O0 -std=gnu++0x -c myMF.cpp myMF.cpp:21:6: error: 'type' is not a class, namespace, or enumeration make: [using] Error 1 (ignored)
Compilation finished at Thu Feb 3 17:04:44
I guess the easiest solution is to just give up the metafunction forwarding and have: template < class MF, class T > struct myMF { typedef typename boost::mpl::apply<MF,T>::type type; BOOST_STATIC_CONSTANT(bool,value=type::value); }; This seems to work everywhere.

On 2/3/2011 6:02 PM, Steven Watanabe wrote:
AMDG
On 2/3/2011 2:42 PM, Edward Diener wrote:
Compiling this code with gcc:
#include <boost/config.hpp> #include <boost/mpl/apply.hpp>
template < class MF, class T
struct myMF : boost::mpl::apply<MF,T> { BOOST_STATIC_CONSTANT(bool,value=type::value); };
int main() { return 0; }
Gives:
"gcc.compile.c++ ..\..\..\bin.v2\libs\tti\test\TestMFHasTypeMFC.test\gcc-mingw-4.5.2\debug\TestMFHasTypeMFC.o
TestMFHasTypeMFC.cpp:18:5: error: 'type' has not been declared
gcc is correct. Members of a dependent base class are not visible in the derived class. (This is necessary to allow the template to be parsed before the template arguments are known.).
You are correct.
Add using typename boost::mpl::apply<MF,T>::type;
This should work but gcc does not like it and gives: error: 'type' is not a class or namespace. Simply forgetting about metafunction forwarding and using the tried and true: typedef typename boost::mpl::apply<MF,T>::type type; BOOST_STATIC_CONSTANT(bool,value=type::value); works everywhere.

On Thu, Feb 3, 2011 at 6:02 PM, Steven Watanabe <watanabesj@gmail.com> wrote:
n 2/3/2011 2:42 PM, Edward Diener wrote:
Compiling this code with gcc:
#include <boost/config.hpp> #include <boost/mpl/apply.hpp>
template < class MF, class T > struct myMF : boost::mpl::apply<MF,T> { BOOST_STATIC_CONSTANT(bool,value=type::value); };
int main() { return 0; }
Gives:
"gcc.compile.c++
..\..\..\bin.v2\libs\tti\test\TestMFHasTypeMFC.test\gcc-mingw-4.5.2\debug\TestMFHasTypeMFC.o
TestMFHasTypeMFC.cpp:18:5: error: 'type' has not been declared
gcc is correct. Members of a dependent base class are not visible in the derived class. (This is necessary to allow the template to be parsed before the template arguments are known.).
Add using typename boost::mpl::apply<MF,T>::type;
This is easier, neh? struct myMF : boost::mpl::apply<MF,T> { BOOST_STATIC_CONSTANT(bool,value=myMF::type::value); }; On the other hand, if this thing is returning an MPL integral constant, why wouldn't you simply: struct myMF : boost::mpl::apply<MF,T>::type {}; and be done with it? -- Dave Abrahams BoostPro Computing http://www.boostpro.com

On 2/4/2011 12:02 PM, Dave Abrahams wrote:
On Thu, Feb 3, 2011 at 6:02 PM, Steven Watanabe<watanabesj@gmail.com> wrote:
n 2/3/2011 2:42 PM, Edward Diener wrote:
Compiling this code with gcc:
#include<boost/config.hpp> #include<boost/mpl/apply.hpp>
template < class MF, class T
struct myMF : boost::mpl::apply<MF,T> { BOOST_STATIC_CONSTANT(bool,value=type::value); };
int main() { return 0; }
Gives:
"gcc.compile.c++
..\..\..\bin.v2\libs\tti\test\TestMFHasTypeMFC.test\gcc-mingw-4.5.2\debug\TestMFHasTypeMFC.o
TestMFHasTypeMFC.cpp:18:5: error: 'type' has not been declared
gcc is correct. Members of a dependent base class are not visible in the derived class. (This is necessary to allow the template to be parsed before the template arguments are known.).
Add using typename boost::mpl::apply<MF,T>::type;
This is easier, neh?
struct myMF : boost::mpl::apply<MF,T> { BOOST_STATIC_CONSTANT(bool,value=myMF::type::value); };
On the other hand, if this thing is returning an MPL integral constant, why wouldn't you simply:
struct myMF : boost::mpl::apply<MF,T>::type {};
and be done with it?
The last suggestion works well, as does the first. But I have some confusion about boost::mpl::apply which neither your MPL book nor the Boost docs clears up for me. As I understand it 'apply' invokes the 'apply' metafunction in a metafunction class and apply<...>::type returns the invoked metafunction's type. If I am deriving from the metafunction's type, then 'myMF' itself does not have a 'type' but only a 'value'. Is this correct or do I have a basic misunderstanding of how boost::mpl::apply works ?

On 2/4/2011 5:11 PM, Edward Diener wrote:
On 2/4/2011 12:02 PM, Dave Abrahams wrote:
On Thu, Feb 3, 2011 at 6:02 PM, Steven Watanabe<watanabesj@gmail.com> wrote:
n 2/3/2011 2:42 PM, Edward Diener wrote:
Compiling this code with gcc:
#include<boost/config.hpp> #include<boost/mpl/apply.hpp>
template < class MF, class T
struct myMF : boost::mpl::apply<MF,T> { BOOST_STATIC_CONSTANT(bool,value=type::value); };
int main() { return 0; }
Gives:
"gcc.compile.c++
..\..\..\bin.v2\libs\tti\test\TestMFHasTypeMFC.test\gcc-mingw-4.5.2\debug\TestMFHasTypeMFC.o
TestMFHasTypeMFC.cpp:18:5: error: 'type' has not been declared
gcc is correct. Members of a dependent base class are not visible in the derived class. (This is necessary to allow the template to be parsed before the template arguments are known.).
Add using typename boost::mpl::apply<MF,T>::type;
This is easier, neh?
struct myMF : boost::mpl::apply<MF,T> { BOOST_STATIC_CONSTANT(bool,value=myMF::type::value); };
On the other hand, if this thing is returning an MPL integral constant, why wouldn't you simply:
struct myMF : boost::mpl::apply<MF,T>::type {};
and be done with it?
The last suggestion works well, as does the first.
But I have some confusion about boost::mpl::apply which neither your MPL book nor the Boost docs clears up for me. As I understand it 'apply' invokes the 'apply' metafunction in a metafunction class and apply<...>::type returns the invoked metafunction's type. If I am deriving from the metafunction's type, then 'myMF' itself does not have a 'type' but only a 'value'. Is this correct or do I have a basic misunderstanding of how boost::mpl::apply works ?
Never mind. The fog in my brain has cleared and I see what is happening. Thanks for your help !
participants (5)
-
Dave Abrahams
-
Edward Diener
-
Jeffrey Lee Hellrung, Jr.
-
Larry Evans
-
Steven Watanabe