1
votes

I have a template class A with a type argument T. My program generates several versions for the type argument - T_1, .. , T_N. Further, for each type T_i, the code with A<T_i> is compiled into a library lib_i. Finally, for each lib_i, I call a function from A<T_i>. However, I'm always getting result corresponding to T_1. What could be the problem?

Here is more detail.

File structure:

  • A.hpp
  • lib1
    • main1.cpp
    • T1.hpp
    • lib1.so
  • lib2
    • main2.cpp
    • T2.hpp
    • lib2.so
  • libN
    • mainN.cpp
    • TN.hpp
    • libN.so

Example:

A.hpp:

template <class T>
class A
{
    void foo()
    {
        std::cout << T::K << std::endl;
    }
};

T1.hpp:

class T1
{
    enum { K = 1 };
};

T2.hpp:

class T2
{
    enum { K = 2 };
};

Both main1.cpp and main2.cpp call A::foo(). But the output is always 1.

UPDATE

main1.cpp:

#include "../A.hpp"
#include "T1.hpp"

int main(int argc, char **argv)
{
    A<T1> a;
    a.foo();
    return 0;
}

main2.cpp:

#include "../A.hpp"
#include "T2.hpp"

int main(int argc, char **argv)
{
    A<T2> a;
    a.foo();
    return 0;
}

UPDATE2:

This happens on mac os x.

g++ -v

Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/opt/local/libexec/gcc/x86_64-apple-darwin11/4.7.2/lto-wrapper Target: x86_64-apple-darwin11 Configured with: ../gcc-4.7.2/configure --prefix=/opt/local --build=x86_64-apple-darwin11 --enable-languages=c,c++,objc,obj-c++,lto,fortran,java --libdir=/opt/local/lib/gcc47 --includedir=/opt/local/include/gcc47 --infodir=/opt/local/share/info --mandir=/opt/local/share/man --datarootdir=/opt/local/share/gcc-4.7 --with-libiconv-prefix=/opt/local --with-local-prefix=/opt/local --with-system-zlib --disable-nls --program-suffix=-mp-4.7 --with-gxx-include-dir=/opt/local/include/gcc47/c++/ --with-gmp=/opt/local --with-mpfr=/opt/local --with-mpc=/opt/local --with-ppl=/opt/local --with-cloog=/opt/local --enable-cloog-backend=isl --disable-cloog-version-check --enable-stage1-checking --enable-lto --enable-libstdcxx-time --with-as=/opt/local/bin/as --with-ld=/opt/local/bin/ld --with-ar=/opt/local/bin/ar --with-bugurl=https://trac.macports.org/newticket --disable-ppl-version-check --with-pkgversion='MacPorts gcc47 4.7.2_2+universal' Thread model: posix gcc version 4.7.2 (MacPorts gcc47 4.7.2_2+universal)

However it works correctly on linux.

g++ -v

Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/gcc_4_7/libexec/gcc/x86_64-linux-gnu/4.7.0/lto-wrapper Target: x86_64-linux-gnu Configured with: ../gcc-4.7.0/configure --build=x86_64-linux-gnu --prefix=/usr/gcc_4_7 --with-gmp=/usr/gcc_4_7 --with-mpfr=/usr/gcc_4_7 --with-mpc=/usr/gcc_4_7 --enable-checking=release --enable-languages=c,c++,fortran --disable-multilib --program-suffix=-4.7 Thread model: posix gcc version 4.7.0 (GCC)

UPDATE3:

My explanation was misleading because I was actually creating files with the same names (lib1/T.hpp, lib2/T.hpp, .. ). The names of the types T_i were also the same. The correct one was chosen by including T.hpp from the corresponding directory. Using different names for T_i (not for T_i.hpp) solved the problem. However, I'm still wondering what was wrong when the typenames were the same.

1
There is no A::foo(). Did you mean A<T_i>::foo()?StoryTeller - Unslander Monica
@StoryTeller, yes, of course, I wrote it in the text.nil
Yes, well, I had to scroll to read the end. :) Anyway, please post main1.cpp and main2.cpp.StoryTeller - Unslander Monica
And also, how is each lib_i generated exactly?StoryTeller - Unslander Monica
@StoryTeller, for each lib_i, I create a directory using system("mkdir ... Then in each directory, I generate files T.hpp and main.cpp (they actually have the same names, not T1.hpp, T2.hpp etc). I also copy a Makefile into the directory and then I call system("make -C ... Finally, I use dlopen, dlsym to call the function.nil

1 Answers

1
votes

I tried your codes and it works fine. A<T2> a; a.foo() will output 2.

I am afraid the wrong codes are linked since T.hpp and main.cpp have the same names.

You might want to use different file names. :)