explicit specialization of methods of a template class in several .so

  • (2 Pages)
  • +
  • 1
  • 2

16 Replies - 2147 Views - Last Post: 22 June 2011 - 09:21 AM Rate Topic: -----

#1 tlknv  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 21-June 11

explicit specialization of methods of a template class in several .so

Posted 21 June 2011 - 06:51 AM

Hi All,

I need a confirmation that what I do is perfectly correct and I need to learn documents that confirm that.
I have a template class (template <class T> class C) which is defined in the shared library "a". Some of the methods of the class C are specialized/defined explicitly for some particular type TT in the same shared library "a" and an object of C<TT> is constructed in this library as well. One method ( ex: void C::f() ) is not specialized explicitly for type TT in library "a" but specialized in another shared library "b". Just in case: C<T>::f() has some compilable definition for any type T, ex: template<class T> void C<T>::f(){} in library "a".
Library "b" is not always linked to "a". If it's not linked then the default C<T>::f() is called (which does nothing).
If "b" is linked to "a" then explicitly specialized C<TT>::f() which resides in "b" is called. This is what I expect.
Is it standard behavior? Is it documented somewhere? Where?
I'm using gcc under linux and the code is compiled for FreeBSD.

Thanks,
Boris

Is This A Good Question/Topic? 0
  • +

Replies To: explicit specialization of methods of a template class in several .so

#2 Salem_c  Icon User is online

  • void main'ers are DOOMED
  • member icon

Reputation: 1635
  • View blog
  • Posts: 3,111
  • Joined: 30-May 10

Re: explicit specialization of methods of a template class in several .so

Posted 21 June 2011 - 08:15 AM

So others can check if they're about to waste time by saying what has already been said
Was This Post Helpful? 0
  • +
  • -

#3 tlknv  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 21-June 11

Re: explicit specialization of methods of a template class in several .so

Posted 21 June 2011 - 08:22 AM

I'm going to close the threads as soon as I get an answer.
Was This Post Helpful? 0
  • +
  • -

#4 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: explicit specialization of methods of a template class in several .so

Posted 21 June 2011 - 03:04 PM

Well first off lets simplify this a bit so we can maybe ask a coherent question.

There is a template class Foo<T> declared in say "foo.hpp". And Inside of Foo there is a template function bar<TT>().

There are two .cpp files: FooBar.cpp and main.cpp -- FooBar.cpp declares a template specialization of say: Foo<int>::bar<double>() and the question is: if one uses Foo<int>::bar<double> in main.cpp will it call the default Foo<int>::bar<TT>() declared in foo.hpp OR will the linker resolve any conflict and bind to the specialization?

Its an interesting question and I *think* the answer is that the linker will not bind to specialization when in main.cpp because it is not declared where the compiler can see it when compiling main.cpp:

example.

foo.hpp:
#if !defined(FOO_H)
#define FOO_H

template <typename T> class Foo {
    T data;
    public:
    Foo(T in) : data(in) { }

    template<typename TT> void bar(TT value) {
        cout << "default: " << static_cast<T>(value)*data << endl;
    }

};

void doSpecializedTest();

#endif


foobar.cpp:
#include "foo.hpp"
#include <iostream>

using namespace std;

template <>
class Foo<int> {
    int data;
    public:
    Foo(int in) : data(in) { }

    template<typename TT> void bar(TT value) {
        cout << "default: " << static_cast<int>(value)*data << endl;
    }
    
    template<> void bar(double value) {
        cout << "special: " << value*data << endl;
    }

};

void doSpecializedTest() {
    Foo<int> fooInt(10);
    double pi = 3.14159265;
    fooInt.bar(pi);
}


main.cpp:
#include <iostream>
#include "foo.hpp"

using namespace std;

int main() {
    doSpecializedTest(); //call to foobar.cpp
    // then the same test but without explicit specialization.
    Foo<int> fooInt(10);
    double pi = 3.14159265;
    fooInt.bar(pi); // if using default becomes 30
    return 0;
}


output:
> "C:\CProjects\Forum Help\236471-explicit-specialization-of-methods-of-a-template-class-in-several-so\main.exe " 
special: 31.4159
default: 30



So... while I don't have any documentation I can tell you that both minGW and VS2010 produce the same output.

Of course what *SHOULD* be happening is the specializations should be in the .hpp file.
Was This Post Helpful? 0
  • +
  • -

#5 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: explicit specialization of methods of a template class in several .so

Posted 21 June 2011 - 04:21 PM

actually I found a lot of troubles with MinGW once I had the project setup correctly. MinGW/GCC will not compiler the code as stated above. I get an error:

Explicit specialization in non-namespace scope

So to actually get this to work I had to ditch specialization and overload the function.

foobar.cpp:
#include "foo.hpp"
#include <iostream>

using namespace std;

template <>
class Foo<int> {
    int data;
    public:
    Foo(int in) : data(in) { }

    template<typename TT> void bar(TT value) {
        cout << "Foo<int>::default: " << value * data << endl;
    } 
       
    void bar(double value) {
        cout << "Foo<int>::overload: " << value * data << endl;
    }        

};


void doSpecializedTest() {
    Foo<int> fooInt(10);
    double pi = 3.14159265;
    fooInt.bar(pi);
}


however as you might expect the result was exactly the same as before. Because main.cpp can not "see" the specialization it can not use it.
Was This Post Helpful? 0
  • +
  • -

#6 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: explicit specialization of methods of a template class in several .so

Posted 21 June 2011 - 04:39 PM

:/ Actually I was able to make foobar.cpp into:
#include "foo.hpp"
#include <iostream>

using namespace std;

template <>
class Foo<int> {
    int data;
    public:
    Foo(int in) : data(in) { }

    template<typename TT> void bar(TT value) {
        cout << "Foo<int>::default: " << value * data << endl;
    } 
       
    

};

    template<> void Foo<int>::bar<double>(double value) {
        cout << "Foo<int>::overload: " << value * data << endl;
    } 

void doSpecializedTest() {
    Foo<int> fooInt(10);
    double pi = 3.14159265;
    fooInt.bar(pi);
}


which is the "proper" way to create the explicit specialization. The problem here is that the linker complains of multiple definition of void Foo<int>::bar<double>(double)

and VS's linker make a similar complaint.


So can you give us an example of what you are trying to ask about?
Was This Post Helpful? 0
  • +
  • -

#7 tlknv  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 21-June 11

Re: explicit specialization of methods of a template class in several .so

Posted 21 June 2011 - 05:20 PM

Hi NickDMax,
Thank you for the reply. I'm sorry for the confusing description, my case is somewhat easier. The simplified code can look like this:
--------------------------
foo.hpp:
template <class T> class C {
public:
  void f()
  {
  }
  int aaa(int bbb)
  {
	return bbb + 88;
  }
};
--------------------------
foobar_a.cpp
#include "foo.hpp"
template <> int C<int>::aaa(int bbb)
{
  return -555 - bbb;
}
static C<int> static_c;
--------------------------
foobar_b.cpp
#include "foo.h"
#include "stdlib.h"
template <> void C<int>::f()
{
  exit(3);
}
--------------------------
main_a.cpp
#include "foo.hpp"

int main()
{
  C<int> c;
  c.f();
  return 0;
}
--------------------------


foobar_a.cpp belongs to some shared/dynamic library "a".
foobar_b.cpp belongs to some shared/dynamic library "b".
main_a.cpp is either belongs to shared library "a" or linked to "a" anyhow.

In the sample above neither of functions aaa(int) is needed and can be ignored but I provide them to match my original post: "Some of the methods of the class C are specialized/defined explicitly for some particular type TT in the same shared library "a" and an object of C<TT> is constructed in this library as well."

Shared library "b" may be linked to shared library "a" or maybe not linked depending on some particular application.
I see that for the applications which have no "b" linked to "a" the default/generic implementation of f() is called ( which is defined in foo.hpp ). However for the applications which link "b" (dynamically) to "a" the explicitly defined specialization C<int>::f() is called ( which is defined in foobar_b.cpp ). I think that this is a proper and expected behavior however I need some document that confirms/profs that, ex: c++ standard or g++ documentation or something else.

Thanks,
Boris
Was This Post Helpful? 0
  • +
  • -

#8 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: explicit specialization of methods of a template class in several .so

Posted 22 June 2011 - 02:54 AM

Well I compiled your program in multiple compilers and while visual studio was willing to compile the example it used the default C::f function defined in foo.h

On the other hand MinGW (GCC 4.6.0) would not link it due to multiple definitions of C<int>::f()

I have tried many variations trying to get it to work and I have to say that I just don't think that it is possible. While template classes do have linkage I don't think it gets as granular as allowing explicit specialization across translation units. However you can find copies of the standard (draft copies are easier to find but may not represent the "truth" until it has been finalized).

I would give you my read on it but I am no standards lawyer and I get easily confused by the wording.
Was This Post Helpful? 0
  • +
  • -

#9 tlknv  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 21-June 11

Re: explicit specialization of methods of a template class in several .so

Posted 22 June 2011 - 03:55 AM

Thank you NickDMax. I was afraid that this might not work with some compilers or some way of dynamic linkage however it works with g++.
Was This Post Helpful? 0
  • +
  • -

#10 tlknv  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 21-June 11

Re: explicit specialization of methods of a template class in several .so

Posted 22 June 2011 - 05:51 AM

I tried to find something if the C++ standard before posting my question to classify my case as: standard conformed, or compiler/system specific/unpredictable. I didn't find that however I didn't find anything in the standard that says against the observed behavior either. Also I tried to find this case in g++ documentation and failed.
Was This Post Helpful? 0
  • +
  • -

#11 tlknv  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 21-June 11

Re: explicit specialization of methods of a template class in several .so

Posted 22 June 2011 - 08:09 AM

I got the answer at codeguru forum:
C++0x-draft-n3092, 14.7.3.6
If a template, a member template or the member of a class template is explicitly specialized then that
specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required. If the program does not provide a definition for an explicit specialization and either the specialization is used in a way that would cause an implicit instantiation to take place or the member is a virtual member function, the program is ill-formed, no diagnostic required. An implicit instantiation is never generated for an explicit specialization that is declared but not defined.
Was This Post Helpful? 0
  • +
  • -

#12 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: explicit specialization of methods of a template class in several .so

Posted 22 June 2011 - 08:27 AM

View Posttlknv, on 22 June 2011 - 06:55 AM, said:

Thank you NickDMax. I was afraid that this might not work with some compilers or some way of dynamic linkage however it works with g++.

no, it worked with your version of g++.

It did not work with my version of g++ ported to windows.
Was This Post Helpful? 1
  • +
  • -

#13 tlknv  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 21-June 11

Re: explicit specialization of methods of a template class in several .so

Posted 22 June 2011 - 08:37 AM

NickDMax, I guess that possibly the behavior that I observed uses some feature of .so linking like weak symbols which don't work the same way with Windows port of g++.
Was This Post Helpful? 0
  • +
  • -

#14 tlknv  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 21-June 11

Re: explicit specialization of methods of a template class in several .so

Posted 22 June 2011 - 08:47 AM

Sorry, I guess I didn't provide a piece of the code that matters to reproduce the behavior:
--------------------------
foo.hpp:
class B {
public:
  virtual void f() = 0;
};
template <class T> class C : public B {
...
};
--------------------------


Was This Post Helpful? 0
  • +
  • -

#15 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6048
  • View blog
  • Posts: 23,473
  • Joined: 23-August 08

Re: explicit specialization of methods of a template class in several .so

Posted 22 June 2011 - 09:01 AM

Don't waste your time. This was spammed all over the net and apparently answered elsewhere: http://cboard.cprogr...tml#post1034986
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2