WoJ*_*oJo 5 c++ gcc templates mingw visual-c++
我专门设计了一个模板,在MSVC编译器和MinGW/GCC之间遇到了不同的问题.这是头文件:
// MyClass.h
#ifndef MYCLASS_HEADER
#define MYCLASS_HEADER
template<typename T>
class MyClass {
public:
virtual void doSomething() {
// some code
}
};
// specialization prototype here
#endif
Run Code Online (Sandbox Code Playgroud)
现在,差异.为了避免多个定义,我只在头文件中专门设计原型,实现在cpp文件中.专业化是问题所在.GCC/MinGW编译器只接受这一个:
template<> void MyClass<int>::doSomething(); // GCC version
Run Code Online (Sandbox Code Playgroud)
而MSVC只有这个:
extern template void MyClass<int>::doSomething(); // MSVC version
Run Code Online (Sandbox Code Playgroud)
CPP文件中的实现对于两者都是相同的:
// MyClass.cpp
#include "MyClass.h"
template<> void MyClass<int>::doSomething() {
// some code
}
Run Code Online (Sandbox Code Playgroud)
使用GCC原型,MSVC编译器抛出"未解析的外部符号"错误,GCC与MSVC版本抛出"实例化后......的专业化".
目前,我有解决方法:
#ifdef _MSC_VER
extern template
#else
template<>
#endif
void MyClass<int>::doSomething();
Run Code Online (Sandbox Code Playgroud)
在头文件中.它有效,但我不喜欢它.有没有办法避免编译器特定的开关?
这些不是一回事:
template<> void MyClass<int>::doSomething(); // GCC version
extern template void MyClass<int>::doSomething(); // MSVC version
Run Code Online (Sandbox Code Playgroud)
第一个声明的明确分工,第二个声明了一个明确的实例.
使用GCC原型,MSVC编译器抛出"未解析的外部符号"错误,GCC与MSVC版本抛出"实例化后......的专业化".
GCC错误告诉您MyClass<int>::doSomething()文件中早先存在隐式实例化,而不是显式特化的声明; 这是代码中的错误.您必须在使用它之前声明显式特化,这会导致隐式实例化,否则隐式实例化将使用主模板定义,而不是特化.在任何实例化之前,通常可以确保在使用之前声明特化,方法是在主模板定义之后直接声明特化MyClass<int>.
我不知道为什么你得到MSVC错误,听起来好像你没有链接到MyClass.cpp.如果不是这样,您可以尝试添加显式实例化定义MyClass.cpp以强制在该文件中发出符号:
template void MyClass<int>::doSomething(); // N.B. no "extern" on definition
Run Code Online (Sandbox Code Playgroud)
您是否尝试宣告 双方的专业化和实例,但确保他们宣布之前任何隐含的实例?这应该是有效的C++,例如
#ifndef MYCLASS_H
#define MYCLASS_H
template<typename T>
class MyClass {
public:
virtual void doSomething() {
// some code
}
};
// declare explicit specialization
template<> void MyClass<int>::doSomething();
// declare explicit instantiation
extern template void MyClass<int>::doSomething();
#endif
Run Code Online (Sandbox Code Playgroud)
.
// MyClass.cpp
#include "MyClass.h"
// define explicit specialization
template<> void MyClass<int>::doSomething() {
// some code
}
// define explicit instantiation
template void MyClass<int>::doSomething();
Run Code Online (Sandbox Code Playgroud)
或者,如果您无法使用两个编译器,则可以将专用成员函数的定义放在标头中并声明它inline,这也可以避免多个定义错误.
| 归档时间: |
|
| 查看次数: |
2212 次 |
| 最近记录: |