【发布时间】:2014-10-23 07:25:24
【问题描述】:
最近发现了模板,我一直在尝试很好地掌握它们,并遇到了我非常想实现的它们的用法;但是尝试了多种方法后,我不断收到错误。
我正在尝试创建一个可以以任意顺序一次获取多种类型参数的函数。
(我使用的是 VS 2013。)
我现在遇到的是一个“已定义”错误(仅当在多个文件中包含tem.h 时):
确切的第一个错误(其余的基本相同,只是每个测试..重载?):
Error 1 error LNK2005: "void __cdecl test<struct A>(struct A *)" (??$test@UA@@$$$V@@YAXPAUA@@@Z) already defined in main.obj c:\Users\User\documents\visual studio 2013\Projects\TemplateTest\TemplateTest\foo.obj TemplateTest
foo 只是一个 .cpp 文件,仅包含:#include "tem.h"
tem.h:
#ifndef TEM_H
#define TEM_H
struct A {};
struct B {};
#include <iostream>
template<typename First, typename... Rest>
void test(First *t, Rest&&... args){
test(t);
test(std::forward<Rest>(args)...);
}
template<>
void test<A>(A *val){
std::cout << "Handled A" << std::endl;
}
template<>
void test<B>(B *val){
std::cout << "Handled B" << std::endl;
}
#endif
main.cpp:
#include <iostream>
#include "tem.h"
int main(int argc, char *argv[]){
std::cout << "running test..." << std::endl;
A a;
B b;
test(&a, &b);
return 0;
}
我错过了什么导致此错误?
编辑: 使每个测试实例内联可以防止错误,但我认为这并不是最好的解决方案
【问题讨论】:
-
究竟已经定义了什么?始终显示完整的未编辑错误消息。
-
@n.m.
Error 1 error LNK2005: "void __cdecl test<struct A>(struct A *)" (??$test@UA@@$$$V@@YAXPAUA@@@Z) already defined in main.obj c:\Users\User\documents\visual studio 2013\Projects\TemplateTest\TemplateTest\foo.obj TemplateTest和更多类似的。 foo 只是一个 c++ 源文件,顶部有#include "tem.h" -
这个问题在 StackOverflow 上有 4,206,904 个重复项
-
@JonathanWakely 最初它的格式是为了解决这个问题,即使尝试解决方案发现我仍然遇到错误,但它被标记为一个问题的重复,该问题的解决方案已经尝试过,但有错误
-
查看您的原始问题,问题出在未在标题中定义且未在
tem.cpp中实例化的主模板(可变参数模板)上,因此您遇到了缺少定义错误。您通过在标题中定义 everything 来修复它的尝试扭转了这种情况,这会产生多个定义错误。解决方案是内联定义所有内容(并将inline放在特化上!)或将主要(即非特化)函数模板放在标题中,并将特化放在 .cpp 文件中。
标签: c++ visual-studio-2013 variadic-templates multiple-definition-error