【问题标题】:Explicit specialization has already been instantiated显式特化已被实例化
【发布时间】:2019-07-26 12:57:26
【问题描述】:

我想将模板化函数的特化实现放到一个单独的源文件中,但是如果我尝试调用它(在 MyAction 中),我会收到以下错误:

Explicit specialization has already been instantiated

我不知道为什么会出现此错误。 示例代码:

ma​​in.cpp

#include <iostream>
#include <string>

#include "MyClass.h"

int main()
{
    std::cout << "Hello, " << XX::MyClass().MyMethod<1>() << std::endl;
    std::cin.get();
}

MyClass.h

#pragma once

#include <string>

namespace XX {

    struct MyClass {

        std::string MyAction() {
            return MyMethod<0>() + MyMethod<1>();
        }

        template<int>
        std::string MyMethod();

    };

    template<>
    std::string MyClass::MyMethod<0>();

    template<>
    std::string MyClass::MyMethod<1>();

}

MyClass.cpp

#include "MyClass.h"

namespace XX {

    template<>
    std::string MyClass::MyMethod<0>() {
        return "FOO";
    }

    template<>
    std::string MyClass::MyMethod<1>() {
        return "BAR";
    }

}

是否有我不知道的模板实例化规则?

【问题讨论】:

  • VisualStudio 2017
  • 我认为您不能将模板函数放在 cpp 文件中并从另一个翻译单元调用它们。据我所知,模板函数需要在头文件中或直接在调用它们的 cpp 文件中。
  • @rashmatash 不一定。如果您列出将使用的每个实例,则没有什么可以阻止您将模板放入 CPP。然而,这并不总是可行的。
  • 是的,他可以。必须至少有一个翻译单元定义了模板的特定工具,其他翻译单元可以在不看定义的情况下使用它。

标签: c++


【解决方案1】:

好的,看起来问题是订单。

当您定义MyAction 时,编译器尝试实例化模板,但他不知道专门化。

当您声明 MyAction 并在模板特化后在 cpp 中定义它时,它将起作用。

// header part
#include <string>

namespace XX {
    struct MyClass {
        template<int>
        std::string MyMethod();
        std::string MyAction();
    };
}

// cpp part
namespace XX {
    template<>
    std::string MyClass::MyMethod<0>() {
        return "a";
    }

    template<>
    std::string MyClass::MyMethod<1>() {
        return "b";
    }

    std::string MyClass::MyAction() {
        return MyMethod<0>() + MyMethod<1>();
    }
}

请看这里:https://godbolt.org/z/aGSB21

请注意,如果您将MyClass::MyAction() 移动到MyClass::MyMethod&lt;1&gt;() 上方,错误将会回来。

这是可以在头文件中声明特化的版本:https://godbolt.org/z/kHjlne

【讨论】:

    猜你喜欢
    • 2019-11-01
    • 1970-01-01
    • 2011-12-08
    • 1970-01-01
    • 2019-04-15
    • 1970-01-01
    • 2012-09-25
    • 2020-11-16
    • 2014-09-23
    相关资源
    最近更新 更多