C++: Templates not working from another class

When the following project is compiled, I get the following compiler error: (Visual Studio 2010)

1>usingclass.obj : error LNK2019: unresolved external symbol "public: static int __cdecl c1::arrSize(int * const)" (??$arrSize@H@c1@@SAHQAH@Z) referenced in function "public: void __thiscall usingclass::a(void)" (?a@usingclass@@QAEXXZ)

Code:

Headers:

c1.h

#pragma once
#include <array>
class c1
{
    c1(void);
    ~c1(void);
public:
    template<class T>
    static int arrSize(T arr[]);
};

usingclass.h

#pragma once
#include "c1.h"

class usingclass
{
public:
    usingclass(void);
    ~usingclass(void);
    void a();
};

Source files:

c1.cpp

#include "c1.h"

c1::c1(void)
{
}


c1::~c1(void)
{
}

template <class T>
int c1::arrSize(T arr[])
{
    return (sizeof(arr)/sizeof(arr[0]));
}

usingclass.cpp

#include "usingclass.h"

usingclass::usingclass(void)
{
}


usingclass::~usingclass(void)
{
}

void usingclass::a()
{
    int a[2] = {1,2};
    int b = c1::arrSize<int>(a);
}

How do I fix that?


You need to move

template <class T>
int c1::arrSize(T arr[])
{
    return (sizeof(arr)/sizeof(arr[0]));
}

inside c1.h .

Template implementations must be visible to all translation units using that template (unless it's specialized, and in your case it's not).

This solves the compiler error but the underlying issue is solved with Vaughn Cato's answer. I missed that. You'll still need the definition in the header.


Don't do this! The declaration is misleading.

template <class T>
int c1::arrSize(T arr[])
{
    return (sizeof(arr)/sizeof(arr[0]));
}

is equivalent to

template <class T>
int c1::arrSize(T *arr)
{
    return (sizeof(arr)/sizeof(arr[0]));
}

which will not give you want you want. The proper way to do it is like this:

class c1
{
    c1(void);
    ~c1(void);
public:
    template<class T,int N>
    static int arrSize(T (&arr)[N]) { return N; }
};

arrSize takes a reference to an array as a parameter. The type of the array and the size of the array are template parameters and can be deduced by the compiler. The inline member function then just returns the size determined by the compiler.


I think you have to define your template in c1.h itself. Because when you are including c1.h in your usingclass.h, and try to use template it does not find the expansion for template.

Or If you want to go with implementation of template in c1.cpp, then you have to include c1.cpp as well in usingclass.h.

链接地址: http://www.djcxy.com/p/37134.html

上一篇: 头文件中的C ++模板

下一篇: C ++:模板不能从另一个类运行