Google
 
Webnews.only-4-geeks.com
Interesting places
news.only-4-geeks.com Forum Index » C++

template function can't be instantilized (use keyword export

 
Jump to:  
 
Ningyu Shi
PostPosted: Fri Aug 29, 2008 4:39 am    Post subject: template function can't be instantilized (use keyword export
       
I have a small demo with 5 files which describe the problem.

b.h:

#ifndef BB
#define BB
class B
{
public:
template<typename T> T bf() const;
};
#endif
//////////////////////////
b.cpp:

#include "b.h"
#include <iostream>
using namespace std;
template<> int B::bf<int>() const {cout << "int" << endl;return 10;}
template<> double B::bf<double>() const {cout << "double" <<
endl;return 1.1;}
///////////////////////////////
a.h:

#ifndef AA
#define AA
#include "b.h"
class A
{
public:
template<typename T> T a() const;
private:
B mb;
};
#endif
///////////////////////////////////
a.cpp:

#include "a.h"
template<typename T> T A::a() const {return mb.bf<T>();}
//////////////////////////
main.cpp

#include <iostream>
#include "a.h"
using namespace std;
int main()
{
A *a = new A;
a->a<double>();
return 0;
}

///////////////////////
If I compile the project,

g++ a.cpp b.cpp main.cpp

I get a link error:

main.cpp:(.text+0x83): undefined reference to `double A::a<double>()
const'
collect2: ld returned 1 exit status

which means the A::a<double> is not instantilized. I try to use
'export' to solve this problem, but g++ doesn't support this keyword
atm. If I dump all code into one file, then the problem doesn't show
up. So, is there any work around other than this?

Thanks a lot.
Regards
Ningyu

--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Alberto Ganesh Barbati
PostPosted: Sat Aug 30, 2008 2:40 pm    Post subject: Re: template function can't be instantilized (use keyword ex
       
Ningyu Shi ha scritto:
Quote:
I have a small demo with 5 files which describe the problem.

b.h:

#ifndef BB
#define BB
class B
{
public:
template<typename T> T bf() const;
};
#endif
//////////////////////////
b.cpp:

#include "b.h"
#include <iostream
using namespace std;
template<> int B::bf<int>() const {cout << "int" << endl;return 10;}
template<> double B::bf<double>() const {cout << "double"
endl;return 1.1;}
///////////////////////////////
a.h:

#ifndef AA
#define AA
#include "b.h"
class A
{
public:
template<typename T> T a() const;
private:
B mb;
};
#endif
///////////////////////////////////
a.cpp:

#include "a.h"
template<typename T> T A::a() const {return mb.bf<T>();}
//////////////////////////
main.cpp

#include <iostream
#include "a.h"
using namespace std;
int main()
{
A *a = new A;
a->a<double>();
return 0;
}

///////////////////////
If I compile the project,

g++ a.cpp b.cpp main.cpp

I get a link error:

main.cpp:(.text+0x83): undefined reference to `double A::a<double>()
const'
collect2: ld returned 1 exit status

which means the A::a<double> is not instantilized. I try to use
'export' to solve this problem, but g++ doesn't support this keyword
atm. If I dump all code into one file, then the problem doesn't show
up. So, is there any work around other than this?


In absence of export, the definition of a template must be visible at
the point of instantiation. This is usually achieved by moving the
template definition and *all* specializations in the .h file. In your
case, only the declaration of the template is visible, as the definition
is inside the .cpp file.

HTH,

Ganesh

--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Triple-DES
PostPosted: Sat Aug 30, 2008 2:46 pm    Post subject: Re: template function can't be instantilized (use keyword ex
       
On 29 Aug, 06:39, Ningyu Shi <ShiNin...@gmail.com> wrote:
Quote:
I have a small demo with 5 files which describe the problem.

b.h:

#ifndef BB
#define BB
class B
{
public:
template<typename T> T bf() const;};

#endif
//////////////////////////
b.cpp:

#include "b.h"
#include <iostream
using namespace std;
template<> int B::bf<int>() const {cout << "int" << endl;return 10;}
template<> double B::bf<double>() const {cout << "double"
endl;return 1.1;}
///////////////////////////////
a.h:

#ifndef AA
#define AA
#include "b.h"
class A
{
public:
template<typename T> T a() const;
private:
B mb;};

#endif
///////////////////////////////////
a.cpp:

#include "a.h"
template<typename T> T A::a() const {return mb.bf<T>();}
//////////////////////////
main.cpp

#include <iostream
#include "a.h"
using namespace std;
int main()
{
A *a = new A;
a->a<double>();
return 0;

}

///////////////////////
If I compile the project,

g++ a.cpp b.cpp main.cpp

I get a link error:

main.cpp:(.text+0x83): undefined reference to `double A::a<double>()
const'
collect2: ld returned 1 exit status

which means the A::a<double> is not instantilized. I try to use
'export' to solve this problem, but g++ doesn't support this keyword
atm. If I dump all code into one file, then the problem doesn't show
up. So, is there any work around other than this?

If you know exactly what types your template should be instantiated
with, you can use an 'explicit instantiation directive'. However,
since B::bf is 'explicitly specialized' you can not explicitly
instantiate it. In that case you must put all the template code in the
header file. This is how template code is usually organized (By
including the .cpp file into the .h file).

I recommend reading C++ Templates: The Complete Guide, which explains
template code organization. You may of course find good articles
online as well. Try to google 'template inclusion model'.

Perhaps someone else could explain why you can't mix explicit
instantiation and explicit specialization (14.7/5). It doesn't seem
logical to me.

DP


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
annamalai
PostPosted: Sat Aug 30, 2008 3:15 pm    Post subject: Re: template function can't be instantilized (use keyword ex
       
On Aug 28, 11:39 pm, Ningyu Shi <ShiNin...@gmail.com> wrote:
Quote:
which means the A::a<double> is not instantilized. I try to use
'export' to solve this problem, but g++ doesn't support this keyword
atm. If I dump all code into one file, then the problem doesn't show
up. So, is there any work around other than this?

One work around would be to force an instantiate of the relevant
member function with the data type of interest. In your example, the
following modification will work:

(begin-code)

$ cat a.h
#ifndef AA
#define AA
#include "b.h"
class A
{
public:
template<typename T> T a() const;
private:
void dummy();
B mb;
};
#endif
$ cat a.c

#include "a.h"

template<typename T> T A::a() const {return mb.bf<T>();}

void A::dummy() { a<double>(); }

(end-code)

This is just a work around. The real solution would be to put the
definition of templated member functions in the header files (in the
absence of export keyword).

Rgds,
anna

--
Abusive Language on Internet
LINK


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Guest
PostPosted: Sat Aug 30, 2008 3:28 pm    Post subject: Re: template function can't be instantilized (use keyword ex
       
On Aug 29, 6:39 am, Ningyu Shi <ShiNin...@gmail.com> wrote:
Quote:
If I compile the project,

g++ a.cpp b.cpp main.cpp

I get a link error:

main.cpp:(.text+0x83): undefined reference to `double A::a<double>()
const'
collect2: ld returned 1 exit status

which means the A::a<double> is not instantilized. I try to use
'export' to solve this problem, but g++ doesn't support this keyword
atm. If I dump all code into one file, then the problem doesn't show
up. So, is there any work around other than this?

You can split the code into files, but you have to #include the
implementation from the header. Basically, the compiler needs to see
the template implementation when the template is used.

Not necessary for B, though, since only full specializations exist.

Sebastian


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Salt_Peter
PostPosted: Sat Aug 30, 2008 3:28 pm    Post subject: Re: template function can't be instantilized (use keyword ex
       
On Aug 29, 12:39 am, Ningyu Shi <ShiNin...@gmail.com> wrote:
Quote:
I have a small demo with 5 files which describe the problem.

b.h:

#ifndef BB
#define BB
class B
{
public:
template<typename T> T bf() const;};

#endif
//////////////////////////
b.cpp:

#include "b.h"
#include <iostream
using namespace std;
template<> int B::bf<int>() const {cout << "int" << endl;return 10;}
template<> double B::bf<double>() const {cout << "double"
endl;return 1.1;}
///////////////////////////////
a.h:

#ifndef AA
#define AA
#include "b.h"
class A
{
public:
template<typename T> T a() const;
private:
B mb;};

#endif
///////////////////////////////////
a.cpp:

#include "a.h"
template<typename T> T A::a() const {return mb.bf<T>();}

template int A::a<int>() const;
template double A::a<double>() const;

see:
LINK

Quote:
//////////////////////////
main.cpp

#include <iostream
#include "a.h"
using namespace std;
int main()
{
A *a = new A;
a->a<double>();
return 0;

}

Why allocate on the heap at all?
and then not release the allocation (delete aWink?
Why not label member functions of type A something alse than A::a()?
Specially since you may be confusing the user of your code (ie:ctor
A::A()).

int main()
{
A instance; // better: A a;
instance.a<double>();

A another;
another.a<int>();
}

/*
double
int
*/

Quote:

///////////////////////
If I compile the project,

g++ a.cpp b.cpp main.cpp

I get a link error:

main.cpp:(.text+0x83): undefined reference to `double A::a<double>()
const'
collect2: ld returned 1 exit status

which means the A::a<double> is not instantilized. I try to use
'export' to solve this problem, but g++ doesn't support this keyword
atm. If I dump all code into one file, then the problem doesn't show
up. So, is there any work around other than this?

Thanks a lot.
Regards
Ningyu

--
[ LINK info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Bart van Ingen Schenau
PostPosted: Sat Aug 30, 2008 3:28 pm    Post subject: Re: template function can't be instantilized (use keyword ex
       
Ningyu Shi wrote:

Quote:
I have a small demo with 5 files which describe the problem.

snip - example of separate compilation of template code
///////////////////////
If I compile the project,

g++ a.cpp b.cpp main.cpp

I get a link error:

main.cpp:(.text+0x83): undefined reference to `double A::a<double>()
const'
collect2: ld returned 1 exit status

which means the A::a<double> is not instantilized. I try to use
'export' to solve this problem, but g++ doesn't support this keyword
atm. If I dump all code into one file, then the problem doesn't show
up. So, is there any work around other than this?

You can try to explicitly instantiate the template A::a in a.cpp, but
the usual solution is to just put all the template code in the header
file (either directly, or by #include of an implementation file).

export was meant as a solution for this problem, but as you noticed, it
is not widely supported. And I doubt that it will ever be :-(

Quote:

Thanks a lot.
Regards
Ningyu

Bart v Ingen Schenau

--
a.c.l.l.c-c++ FAQ: LINK
c.l.c FAQ: LINK
c.l.c++ FAQ: LINK

[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Jiang
PostPosted: Sun Aug 31, 2008 8:55 am    Post subject: Re: template function can't be instantilized (use keyword ex
       
On Aug 31, 12:28 am, Bart van Ingen Schenau <b...@ingen.ddns.info>
wrote:
Quote:
Ningyu Shi wrote:
I have a small demo with 5 files which describe the problem.

snip - example of separate compilation of template code

///////////////////////
If I compile the project,

g++ a.cpp b.cpp main.cpp

I get a link error:

main.cpp:(.text+0x83): undefined reference to `double A::a<double>()
const'
collect2: ld returned 1 exit status

which means the A::a<double> is not instantilized. I try to use
'export' to solve this problem, but g++ doesn't support this keyword
atm. If I dump all code into one file, then the problem doesn't show
up. So, is there any work around other than this?

You can try to explicitly instantiate the template A::a in a.cpp, but
the usual solution is to just put all the template code in the header
file (either directly, or by #include of an implementation file).

export was meant as a solution for this problem, but as you noticed, it
is not widely supported. And I doubt that it will ever be :-(


Actually we have at least one compiler supports export keyword.
After adding export keyword to both a.h and b.h, and changing
b.cpp as follows, my Comeau compiler compiles and links without
any problem.

------------------------------------------------------
$ cat b.cpp
#include "b.h"
#include <stdio.h>
#include <typeinfo>
//template<> int B::bf<int>() const {return 10;}
//template<> double B::bf<double>() const {return 1.1;}
template<typename T>
T B::bf() const{
printf("B::bf() type: %s", typeid(T).name());
return 1.1;
}

$ ll *.h *.cpp
-rwxr-xr-x 1 Administrator 76 Aug 31 15:41 a.cpp*
-rwxr-xr-x 1 Administrator 142 Aug 31 15:43 a.h*
-rwxr-xr-x 1 Administrator 271 Aug 31 15:57 b.cpp*
-rwxr-xr-x 1 Administrator 106 Aug 31 15:43 b.h*
-rwxr-xr-x 1 Administrator 90 Aug 31 15:50 main.cpp*

$ como --A *.cpp
C++'ing a.cpp...
Comeau C/C++ 4.3.10.1 (Jun 1 2008 09:39:56) for MS_WINDOWS_x86_Beta2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors [microsoft] C++ noC++0x_extensions

C++'ing b.cpp...
Comeau C/C++ 4.3.10.1 (Jun 1 2008 09:39:56) for MS_WINDOWS_x86_Beta2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors [microsoft] C++ noC++0x_extensions

C++'ing main.cpp...
Comeau C/C++ 4.3.10.1 (Jun 1 2008 09:39:56) for MS_WINDOWS_x86_Beta2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors [microsoft] C++ noC++0x_extensions

$ ll aout
-rwxr-xr-x 1 Administrator 81408 Aug 31 15:58 aout*

------------------------------------------------------

As my D&E(*) showed me, the support for export (by EDG) is very
important because if the above support were not available, the
export could be removed from the C++ standard. A proposal of
removing export from C++ standard was defeated by the vote of
the standard committee members(80 vs 20), because there exists
at least one successful implementation for export keyword.
Fortunately, or unfortunately if you think in another way,
only one implementation is enough to defeat such proposal.

Also I believe icl can do the same thing because icl uses EDG
frontend. For some reasons the support for export keyword was
disabled. :-(

(*) The new added chapater(-1) is available @
LINK

Quote:
Bart v Ingen Schenau

Jiang



--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Jiang
PostPosted: Sun Aug 31, 2008 9:38 am    Post subject: Re: template function can't be instantilized (use keyword ex
       
On Aug 30, 11:40 pm, Alberto Ganesh Barbati <AlbertoBarb...@libero.it>
wrote:
Quote:
Ningyu Shi ha scritto:



I have a small demo with 5 files which describe the problem.

b.h:

#ifndef BB
#define BB
class B
{
public:
template<typename T> T bf() const;
};
#endif
//////////////////////////
b.cpp:

#include "b.h"
#include <iostream
using namespace std;
template<> int B::bf<int>() const {cout << "int" << endl;return 10;}
template<> double B::bf<double>() const {cout << "double"
endl;return 1.1;}
///////////////////////////////
a.h:

#ifndef AA
#define AA
#include "b.h"
class A
{
public:
template<typename T> T a() const;
private:
B mb;
};
#endif
///////////////////////////////////
a.cpp:

#include "a.h"
template<typename T> T A::a() const {return mb.bf<T>();}
//////////////////////////
main.cpp

#include <iostream
#include "a.h"
using namespace std;
int main()
{
A *a = new A;
a->a<double>();
return 0;
}

///////////////////////
If I compile the project,

g++ a.cpp b.cpp main.cpp

I get a link error:

main.cpp:(.text+0x83): undefined reference to `double A::a<double>()
const'
collect2: ld returned 1 exit status

which means the A::a<double> is not instantilized. I try to use
'export' to solve this problem, but g++ doesn't support this keyword
atm. If I dump all code into one file, then the problem doesn't show
up. So, is there any work around other than this?

In absence of export, the definition of a template must be visible at
the point of instantiation. This is usually achieved by moving the
template definition and *all* specializations in the .h file.


Well, even the export support is available, the above program still
should not compile, because the program is ill-formed.

As we know it is not valid to have both the explicit and generated
versions of a template co-exist in the same program. If declaration
of the specialization does not follow the declaration of the
generic template in its header file, things become subtle, especially
for multi-TUs program. (b.cpp and main.cpp for this example).

For the original example, I added the necessary export keywords
for both a.h and b.h, and como showed me that:

------------------------------------------------------

$ cat a.h

#ifndef AA
#define AA
#include "b.h"
class A
{
public:
export template<typename T> T a() const;
private:
B mb;
};

$ cat b.h
#ifndef BB
#define BB
class B
{
public:
export template<typename T> T bf() const;
};

#endif

$ como --A *.cpp
como: Warning: COMO_MS_INCLUDE environment variable missing
C++'ing a.cpp...
Comeau C/C++ 4.3.10.1 (Jun 1 2008 09:39:56) for MS_WINDOWS_x86_Beta2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors [microsoft] C++ noC++0x_extensions

C++'ing b.cpp...
Comeau C/C++ 4.3.10.1 (Jun 1 2008 09:39:56) for MS_WINDOWS_x86_Beta2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors [microsoft] C++ noC++0x_extensions

C++'ing main.cpp...
Comeau C/C++ 4.3.10.1 (Jun 1 2008 09:39:56) for MS_WINDOWS_x86_Beta2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors [microsoft] C++ noC++0x_extensions

C++ prelinker: T1 B::bf<T1>() const [with T1=double] no longer needed
in main.obj
C++ prelinker: executing: c:\ComeauCompiler\bin\como.exe --vc9 --
long_long --remark --A -c main.cpp
como: Warning: COMO_MS_INCLUDE environment variable missing
Comeau C/C++ 4.3.10.1 (Jun 1 2008 09:39:56) for MS_WINDOWS_x86_Beta2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors [microsoft] C++ noC++0x_extensions

C++ prelinker: error: "T1 B::bf<T1>() const [with T1=double]" has been
referenced as both an explicit specialization and a generated
instantiation

---------------------------------------------------------


And IMHO, even export support is available, it is still better to

1. put generic template followed by declarations of the
specializations
within the same include file, and

2. avoid specializing templates coming from an external source

Jiang



--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

Page 1 of 1 .:.

Google
 
Webnews.only-4-geeks.com

Windows Update | C++ | C | PHP | JavaScript | Photoshop | Programming | Windows 2000 | Python | Windows XP | Object | Flash | Flash - ActionScript | Paint Shop Pro | Excel | PowerPoint | Access | Word | Windows 98 | Internet Explorer 6.0 | CorelDraw12 | Java | XML | asm x86 | Linux Mandrake | Linux RedHat | Outlook |  | news from newsgroups |_ | s

Web Templates

Awesome Website Templates ©

opony darmowe smsy karty plastikowe fronty meblowe bezpieczeństwo pracy