0
考慮這個簡單的連接函數實現。模板函數奇怪的鏈接器錯誤
#include <iostream>
#include <string>
namespace detail {
template<typename... Args>
size_t calcSize(const Args&... args);
inline size_t calcSize(const std::string& head) {
return head.size();
}
template<size_t N>
size_t calcSize(char const(&) [N]) {
return N - 1;
}
template<typename... Tail>
size_t calcSize(const std::string& head, const Tail&... tail) {
return head.size() + calcSize(tail...);
}
template<size_t N, typename... Tail>
size_t calcSize(char const(&) [N], const Tail&... tail) {
return N - 1 + calcSize(tail...);
}
template<typename... Args>
void fillResult(std::string& result,
size_t startIndex,
const Args&... args);
inline void fillResult(std::string& result,
size_t startIndex,
const std::string& head) {
for (size_t i = 0; i < head.size(); ++i) {
if (head[i] == '\0') {
break;
}
result[startIndex++] = head[i];
}
}
template<size_t N>
void fillResult(std::string& result,
size_t startIndex,
char const(&head) [N]) {
for (size_t i = 0; i < N; ++i) {
if (head[i] == '\0') {
break;
}
result[startIndex++] = head[i];
}
}
template<typename... Tail>
void fillResult(std::string& result,
size_t startIndex,
const std::string& head,
const Tail&... tail) {
for (size_t i = 0; i < head.size(); ++i) {
if (head[i] == '\0') {
break;
}
result[startIndex++] = head[i];
}
fillResult(result, startIndex, tail...);
}
template<size_t N, typename... Tail>
void fillResult(std::string& result,
size_t startIndex,
char const(&head) [N],
const Tail&... tail) {
for (size_t i = 0; i < N; ++i) {
if (head[i] == '\0') {
break;
}
result[startIndex++] = head[i];
}
fillResult(result, startIndex, tail...);
}
}
template<typename... Args>
std::string join(const Args&... args) {
std::string result;
result.resize(detail::calcSize(args...));
detail::fillResult(result, 0, args...);
return result;
}
int main() {
std::cout << join("ab", "cd", "ef", "gh") << std::endl;
std::cout << join(std::string("ab"), std::string("cd"), std::string("ef")) << std::endl;
std::cout << join(std::string("ab"), "cd") << std::endl;
//std::cout << join(std::string("ab"), "cd", "ef") << std::endl;
//std::cout << join(std::string("ab"), "cd", std::string("ef")) << std::endl;
return 0;
}
它適用於main中的三個第一行,如果您取消註釋兩個最後一個調用中的任何一個,則鏈接器錯誤失敗。用gcc 4.9和clang嘗試了相同的結果。任何人都可以指出什麼是錯的? 這裏是coliru http://coliru.stacked-crooked.com/a/f55aa64fb4861e43
[演示](http://coliru.stacked-crooked.com/a/db7d6473fedd0cb5) –
感謝,現在的工作。但我仍然不明白爲什麼它是一個**鏈接器**錯誤,而不是編譯錯誤。 – user6256186
@ user6256186:它不合格,不需要診斷。您的程序在遞歸調用中選擇第一個函數模板'template size_t calcSize(const Args&... args)',而不是定義的過載,並且(選定的專用)未定義該模板。 –