typedef as data type for specialized template function in class from shared library

Hi,

I have a class "Result" with a single template function Set(const std::string& arName, T& val) and a specialization of this function Set<Real>(const std::string& arName, Real& val) where Real is a typedef for double. The class is in a shared library and I use it in my main program. If I do result->Set<GLOBAL::Real>("U", 100.0); the wrong template function is called!
I check this by the output with std::cout.

Maybe it's a problem with the typedef.
If I link the object file of the Result class directly to my main program (no shared library), it works.
Could anyone please help me?

Best regards,
Robert


typedefs.hpp:
1
2
3
4
namespace GLOBAL
{
typedef double Real;
}


results.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

namespace GLOBAL
{
class Results
{
  public:
    Results(void);
    virtual ~Results(void);

    template <typename T>
    void Set(const std::string& arName, const T& arValue)
    {
      std::cout << "Error!" << std::endl;
    }
};
}


results.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "results.hpp"
#include "typedefs.hpp"

using namespace GLOBAL;

Results::Results(void)
{
}

Results::~Results(void)
{
}

namespace GLOBAL
{
template <>
void Results::Set<Real>(const std::string& arName, const Real& arValue)
{
   std::cout << "No Error!" << std::endl;
}
}


main.cpp
1
2
3
4
5
6
7
8
9
#include "results.hpp"
#include "typedefs.hpp"

int main(void)
{
  GLOBAL::Results* res = new GLOBAL::Results;
  res->Set<GLOBAL::Real>("U", 100.0);
  return 0;
}
I would guess it is because your specialized function is only in the implementation? There is no prototype of it in your header file aside from the general form.

Also, you have a memory leak in your main function.
Hi Daleth,
thanks for your reply!
I'm new to templates and maybe had some misunderstandings, sorry for that.

I changed results.hpp to
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>

#include "typedefs.hpp"

namespace GLOBAL
{
class Results
{
  public:
    Results(void);
    virtual ~Results(void);

    template <typename T>
    void Set(const std::string& arName, const T& arValue)
    {
      std::cout << "Error!" << std::endl;
    }
};

template <>
void Results::Set<Real>(const std::string& arName, const Real& arValue);
}

and it (of course) works. I see the point you made.

But why do I have to declare it outside my class? If I move my specialization into the class (below the general template function), I get with g++

results.hpp:19:15: error: explicit specialization in non-namespace scope ‘class GLOBAL::Results’
results.hpp:20:66: error: template-id ‘Set<GLOBAL::Real>’ in declaration of primary template
I'm pretty new to templates too. But here is what I found:
http://stackoverflow.com/questions/11085550/why-is-explicit-specialization-of-a-class-template-member-function-allowed-when

David Rodriguez wrote:

...the standard states that specializations must be defined at namespace level in all cases. 14.7.3p2 An explicit specialization shall be declared in a namespace enclosing the specialized template.
Topic archived. No new replies allowed.