实例化后显式专业化

发布于 2024-12-09 23:31:39 字数 1213 浏览 1 评论 0 原文

我有以下代码:

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;
}

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

我收到以下错误:

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

在标记行处。
编译器坚持认为它已经实例化了 DoSomething 。 >,虽然不能,但一个简单的程序可以证明这一点:

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;
}

导致无法解析的外部。
为什么编译器说它已经实例化它,而它不能甚至没有实例化它?为什么编译器不将其视为未解析的符号,而链接器却将其视为未解析的符号? 我知道切换方法顺序可以解决这个问题,但我想知道编译器为什么这样做。

I have the following code:

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;
}

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

岁月无声 2024-12-16 23:31:39

该代码请求在 DoSomething(*i) 进行隐式实例化。您没有在该翻译单元中定义模板的事实意味着它无法实例化专业化,因此 DoSomething(*i) 在您的情况下会产生“无法解析的符号”(链接器-)错误。要消除该错误,您必须在该 TU 中定义模板,或者在定义模板的 TU 中提供该模板的显式实例化指令。

代码请求专门化 DoSomething 的隐式实例化这一事实本身就表明了这一点。 > 在您明确提供专业化足以使程序变得不正确之前(尽管不需要诊断;编译器在这里做得很好,但不需要这样做)。

正如 @CharlesBailey 所指出的,声明显式专业化就完全足够了;它的定义可以在其他地方给出,甚至在使用 TU 之外。

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.

紫罗兰の梦幻 2024-12-16 23:31:39

一般来说,这只是意味着您没有为模板专业化提供“原型”。换句话说,您没有提醒编译器“嘿,该函数的特定类型将会有专门化,所以不要插入错误的函数。”

就我而言,我在 .cpp 文件中有一个模板专门化,并收到此错误。提供“函数原型”(只是模板专业化标头后跟分号,就像常规函数原型一样)解决了问题。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文