显式专业化已经实例化

时间:2019-07-26 12:57:26

标签: c++

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

Explicit specialization has already been instantiated

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

main.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";
    }

}

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

1 个答案:

答案 0 :(得分:4)

好的,问题似乎是订单。

在定义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<1>()上方,错误会再次出现。

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