我创建了有用的辅助方法,如下所示:
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 中获取随机索引并返回该位置的项目。
让我展示第一个例子:
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.
如何修复链接器错误?我应该如何更改代码以内联传递 vector ?
编辑: 这个例子是由 xcode 8.2.1 编译的,随机函数来自 cocos2d-x 库(如果它确实重要的话)。
编辑2: 删除模板代码后开始编译:
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
。所以你不能在那里使用 auto,或者你也应该使用 auto 作为返回类型“item”。但是,如果您将自动和模板结合得太多,您最终可能会得到各种您不想要的类型。
但是下一行也在询问问题:if(items.isEmpty()) return nullptr;
。根据 C++11 标准,sect。 21.4.2.9, basic_string(const charT* s, const Allocator& a = Allocator());
要求:s 不能是空指针。最好你回来T()
.
链接器问题可能与您的构建脚本有关。或者在什么文件中定义所有内容。
关于C++ 使用模板时没有匹配的调用函数,链接器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42111154/