繁体   English   中英

使用模板时 C++ 没有匹配的调用函数,链接器错误

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM