开发者

Explicit specialization after instantiation

开发者 https://www.devze.com 2023-04-13 08:02 出处:网络
I have the following code: typedef vector<int> Vec; typedef vector<Vec> VecOfVec; template<typename Vec>

I have the following code:

typedef vector<int> Vec;
typedef vector<Vec> VecOfVec;

template<typename Vec>
Vec DoSomething(const Vec &v);

template<开发者_如何学C;>
VecOfVec DoSomething<VecOfVec>(const VecOfVec &v)
{
    VecOfVec r;
    for(auto i = v.begin(); i != v.end(); i++)
        r.push_back(DoSomething(*i));
    return r;
}

template<>
Vec DoSomething<Vec>(const Vec &v) // Error here
{
    return v; // for the sake of the example
}

I get the following error:

explicit specialization of 'DoSomething<vector<int> >' after instantiation

at the marked line.

The compiler insists that it already instantiated DoSomething<vector<int> >, while it cannot, and a simple program can prove it:

typedef vector<int> Vec;
typedef vector<Vec> VecOfVec;

template<typename Vec>
Vec DoSomething(const Vec &v);

template<>
VecOfVec DoSomething<VecOfVec>(const VecOfVec &v)
{
    VecOfVec r;
    for(auto i = v.begin(); i != v.end(); i++)
        r.push_back(DoSomething(*i));
    return r;
}

Results in unresolved external.

Why is the compiler saying it already instantiated it when it cannot and even does not? and why doesn't the compiler treat it as unresolved symbol, while the linker does? I know switching the method order solves it, but I want to know why is the compiler doing it.


The code requested an implicit instantiation at DoSomething(*i). The fact that you didn't define the template in that translation unit means that it could not instantiate a specialization, hence DoSomething(*i) yields an "unresolved symbol" (linker-) error in your case. To get rid of that error, you either have to define the template in that TU, or provide an explicit instantiation directive of that template in a TU where you define the template.

The mere fact that the code requested an implicit instantiation for specialization DoSomething<vector<int> > before you explicitly provided that specialization is enough for the program to become ill-formed (without a diagnostic being required though; the compiler does a good job here which it is not required to do).

As @CharlesBailey helpfully notes, declaring the explicit specialization is perfectly sufficient; a definition of it can be given elsewhere, even outside of the using TU.


Generally it just means you didn't provide a "prototype" for the template specialization. In other words you didn't give the compiler a heads up that "hey, there is going to be a specialization for this specific type of the function, so don't plug in the wrong one."

In my case I had a template specialization in a .cpp file, and got this error. Providing a "function prototype" (which is just the template specialization header followed by a semicolon, just like a regular function prototype) fixed the problem.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号