Discussion:
Why does Explicit specialization of function templates cause generation of code?
(too old to reply)
Vyacheslav Lanovets
2005-08-23 07:07:36 UTC
Permalink
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
Maxim Yegorushkin
2005-08-23 08:07:56 UTC
Permalink
Post by 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?
Could you post an example?
Vyacheslav Lanovets
2005-08-23 12:37:21 UTC
Permalink
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)"
(??$***@H@@***@Z) already defined in f1.obj

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

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



Best regards, Vyacheslav Lanovets
Marc Mutz
2005-08-23 13:12:58 UTC
Permalink
Post by Vyacheslav Lanovets
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
Vyacheslav Lanovets
2005-08-24 05:04:58 UTC
Permalink
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
Marc Mutz
2005-08-24 06:43:35 UTC
Permalink
Vyacheslav Lanovets wrote:
<snip>
Post by Vyacheslav Lanovets
Believe it or not, but omitting template arguments for
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>

:o

How useless :)

Thanks,
Marc

Maxim Yegorushkin
2005-08-23 15:17:26 UTC
Permalink
Post by Vyacheslav Lanovets
Hello, Maxim!
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)"
f2.obj : error LNK2005: "bool __cdecl MakeValue<double>(char const
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.
Loading...