Why does Explicit specialization of function templates cause generation of code?

  • Thread starter Vyacheslav Lanovets
  • Start date
V

Vyacheslav Lanovets

Hello, All!

I know that Explicit Instantiation actually emits code to obj files (so you
can even export them from the module as plain functions or classes).

But I found that MSVC7.1 compiler does the same in case of Explicit
Specialization, so I either have to delcare specializations inline or move
definitions to cpp file to avoid LNK2005 ("already defined") errors.

Why is that?

Best regards, Vyacheslav Lanovets
 
M

Maxim Yegorushkin

Vyacheslav said:
Hello, All!

I know that Explicit Instantiation actually emits code to obj files (so you
can even export them from the module as plain functions or classes).

But I found that MSVC7.1 compiler does the same in case of Explicit
Specialization, so I either have to delcare specializations inline or move
definitions to cpp file to avoid LNK2005 ("already defined") errors.

Why is that?

Could you post an example?
 
V

Vyacheslav Lanovets

Hello, Maxim!
You wrote on 23 Aug 2005 01:07:56 -0700:

MY>> But I found that MSVC7.1 compiler does the same in case of Explicit
MY>> Specialization, so I either have to delcare specializations inline or
MY>> move definitions to cpp file to avoid LNK2005 ("already defined")
MY>> errors.
MY>>
MY>> Why is that?

MY> Could you post an example?


Piece of cake :)

=== x.h ===

#pragma once

template <class TTYPE>
bool MakeValue(const char* strValue, TTYPE value)
{
return true;
}

template <>
bool MakeValue(const char* strValue, int value)
{
return true;
}

template <>
bool MakeValue(const char* strValue, double value)
{
return true;
}

=== f1.cpp ===
#include "x.h"

=== f2.cpp ===
#include "x.h"

....
Linking...

f2.obj : error LNK2005: "bool __cdecl MakeValue<int>(char const *,int)"
(??$MakeValue@H@@YA_NPBDH@Z) already defined in f1.obj

f2.obj : error LNK2005: "bool __cdecl MakeValue<double>(char const
*,double)" (??$MakeValue@N@@YA_NPBDN@Z) already defined in f1.obj

Debug/testTemplSpec.exe : fatal error LNK1169: one or more multiply defined
symbols found



Best regards, Vyacheslav Lanovets
 
M

Marc Mutz

Vyacheslav said:
template <>
bool MakeValue(const char* strValue, int value)

dunno what that is, but it's not a full specialisation.
This is:
template <> bool MakeValue<int>(const char *, int value)
Note the <int>.

Marc
 
M

Maxim Yegorushkin

Vyacheslav said:
Hello, Maxim!
You wrote on 23 Aug 2005 01:07:56 -0700:

MY>> But I found that MSVC7.1 compiler does the same in case of Explicit
MY>> Specialization, so I either have to delcare specializations inline or
MY>> move definitions to cpp file to avoid LNK2005 ("already defined")
MY>> errors.
MY>>
MY>> Why is that?

MY> Could you post an example?


Piece of cake :)

=== x.h ===

#pragma once

template <class TTYPE>
bool MakeValue(const char* strValue, TTYPE value)
{
return true;
}

template <>
bool MakeValue(const char* strValue, int value)
{
return true;
}

template <>
bool MakeValue(const char* strValue, double value)
{
return true;
}

=== f1.cpp ===
#include "x.h"

=== f2.cpp ===
#include "x.h"

...
Linking...

f2.obj : error LNK2005: "bool __cdecl MakeValue<int>(char const *,int)"
(??$MakeValue@H@@YA_NPBDH@Z) already defined in f1.obj

f2.obj : error LNK2005: "bool __cdecl MakeValue<double>(char const
*,double)" (??$MakeValue@N@@YA_NPBDN@Z) already defined in f1.obj

Debug/testTemplSpec.exe : fatal error LNK1169: one or more multiply defined
symbols found

Function templates are an exempt of ODR and may be more than one
definition of them in different TU's. Full function template
specialization is not a template, rather an ordinary function, so you
need to use inline keyword not to violate ODR if you want to put them
in a header file included into several TU's.
 
V

Vyacheslav Lanovets

Hello, Marc!
You wrote on Tue, 23 Aug 2005 15:12:58 +0200:

MM> Vyacheslav Lanovets wrote:
MM>> template <>
MM>> bool MakeValue(const char* strValue, int value)

MM> dunno what that is, but it's not a full specialisation.
MM> This is:
MM> template <> bool MakeValue<int>(const char *, int value)
MM> Note the <int>.

Believe it or not, but omitting template arguments for specialization is ok:

14.7.3.11. A trailing template-argument can be left unspecified in the
template-id naming an explicit function template specialization provided it
can be deduced from the function argument type.

And VC++ claims to support this since version 5.0

Regards, Vyacheslav Lanovets
 
M

Marc Mutz

Vyacheslav Lanovets wrote:
Believe it or not, but omitting template arguments for
specialization is ok:

14.7.3.11. A trailing template-argument can be left
unspecified in the template-id naming an explicit
function template specialization provided it can be
deduced from the function argument type.
<snip>

:eek:

How useless :)

Thanks,
Marc
 

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,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top