c++ - C++模板:如何在仅输入1个函数的情况下使用2个类型名?

标签 c++ templates copy ostream

对于下面显示的简单代码:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <unordered_map>
#include <vector>
using namespace std;

static void print(const vector<int>& v) {
    copy(
        begin(v),
        end(v),
        ostream_iterator<int>{cout, ", "}
    );
    cout << endl;
}

int main() {
    vector<pair<int, string>> v {1, 2, 3, 4, 5};

    cout << endl << "In vector:" << endl;
    print(v);

    return 0;
}

我试图将模板编程用于打印目的,因为我想将container概括为任何类型(vectormaplist等),并将元素也推广为任何类型(intdouble等)。
template <typename C, typename T>
static void print(const C& container) {
    copy(
        begin(container),
        end(container),
        ostream_iterator<T>{cout, ", "}
    );
    cout << endl;
}

但是,它不会编译:
In function 'int main()':
prog.cc:31:12: error: no matching function for call to 'print(std::vector<int>&)'
   31 |     print(v);
      |            ^
prog.cc:18:13: note: candidate: 'template<class C, class T> void print(const C&)'
   18 | static void print(const C& container) {
      |             ^~~~~
prog.cc:18:13: note:   template argument deduction/substitution failed:
prog.cc:31:12: note:   couldn't deduce template parameter 'T'
   31 |     print(v);
      |            ^

我的猜测是,类型名称T不是通过函数print()的显式输入,而是由ostream_iterator<int>{cout, ", "}调用的,编译器不知道如何推断其类型(为什么?)。

我想知道如何将两种类型名(CT)传递给print()函数,尽管仅输入typename C

最佳答案

您可能需要在调用T时明确指定print类型(例如print(v, int)),或者编写print以便派生容器本身的值类型。通常的方法是使用typename C::value_type,所有标准容器中都存在:

template <typename C>
void print(const C& container) {
    using T = typename C::value_type;
    copy(
        begin(container),
        end(container),
        ostream_iterator<T>{cout, ", "}
    );
    cout << endl;
}

如果您不喜欢这种方式,或者您的容器可能并不总是具有value_type成员,则可以轻松地直接导出值类型:

template <typename C>
void print(const C& container) {
    using T = std::remove_const_t<decltype(*std::cbegin(container))>;
    copy(
        std::cbegin(container),
        std::cend(container),
        ostream_iterator<T>{cout, ", "}
    );
    cout << endl;
}

关于c++ - C++模板:如何在仅输入1个函数的情况下使用2个类型名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61488219/

相关文章:

c++ - 不带多态性的抽象基类

java - JVM初始化时出错

跨平台代码中的c++模板问题

c++ - 实例化模板时无法访问在类错误中声明的私有(private)成员

python - 在不调用 __init__ 的情况下动态创建 type(self) 的实例?

c++ - 将第一个 k 的元素从一个字符串复制到一个新字符串

c++ - 如何在顶部栏中的VS中设置 “Start without debugging”

c++ - 当类有多个模板参数时专门化成员模板?

ant - 使用 Ant 将文件和文件夹复制到 WEB-INF

c++ - 涉及多态性的极其奇怪的错误?