[英]C++ no matching function for call when using template, linker errors
我创建了有用的辅助方法,如下所示:
template<typename T>
T getRandomItem(vector<T> items){
if(items.isEmpty()) return nullptr;
int i = random(0, (int) items.size() - 1);
return items.at(i);
}
它只是从向量中获取随机索引并返回该位置的项目。
让我展示第一个例子:
vector<string> v = {"foo", "bar"};
string item = getRandomItem(v);
编译器在这里没有发现任何问题,但我收到了非常奇怪的链接器错误:
Undefined symbols for architecture armv7:
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > getRandomItem<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >)", referenced from:
此外,这甚至没有通过编译器:
auto v = {"foo", "bar"};
string item = getRandomItem(v);
我收到以下错误:
No matching function for call to 'getRandomItem'
如果我想内联使用它,它也不起作用:
string item = getRandomItem({"foo", "bar"});
我尝试在这样的参数之前添加:
string item = getRandomItem<string>({"foo", "bar"});
但是,我收到了另一个编译器错误:
Call to 'getRandomItem' is ambiguous.
如何修复链接器错误? 我应该如何更改我的代码以传递内联向量?
编辑:此示例由 xcode 8.2.1 编译,随机函数来自 cocos2d-x 库(如果确实重要)。
edit2:删除模板代码后开始编译:
string getRandomItem(vector<string> items){
if(items.size() == 0) return nullptr;
int i = random(0, (int) items.size() - 1);
return items.at(i);
}
我现在也可以这样做:
string item = getRandomItem({"foo", "bar"});
所以主要问题仍然存在:为什么 xcode 编译器不允许我在这里使用模板?
好吧,首先要做的是: {"foo", "bar"}
显然不会自动解释为字符串。 它被解释为std::initializer_list<const char*>
。 所以没有找到具有std::initializer_list<const char*>
作为输入并返回std::string
std::initializer_list<const char*>
。 所以你不能在那里使用 auto ,或者你也应该使用 auto 作为返回类型“item”。 但是如果你过多地结合 auto 和模板,你最终可能会得到各种你不想要的类型。
但是下一行也在问问题: if(items.isEmpty()) return nullptr;
. 根据 C++11 标准,节。 21.4.2.9, basic_string(const charT* s, const Allocator& a = Allocator());
要求: s 不应是空指针。 最好返回T()
。
链接器问题可能与您的构建脚本有关。 或者在什么文件中定义一切。
我修好了它
#include <vector>
#include <string>
#include <iostream>
#include <time.h>
using namespace std;
template<typename T>
T getRandomItem(vector<T> items) {
if (items.size() == 0) return 0;
int i = rand()%items.size()+0;
return items.at(i);
}
void main() {
srand(time(0));
vector<string> v = { "foo", "bar","test","test2"};
string item = getRandomItem(v);
cout << item<<endl;
}
我能够编译这段代码:
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
using namespace std;
template<typename T>
T getRandomItem(vector<T>& items){ // note that we should pass by reference to prevent extra copy
if(items.size() == 0) return T();
srand(time(NULL));
int i = rand()%items.size()+0;
return items.at(i);
}
int main() {
vector<string> v;
v.push_back("foo");
v.push_back("bar");
string item = getRandomItem(v);
std::cout << item;
return 0;
}
看这里
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.