函数定义 template<typename... folder_t> QString GlobalApplication::document_path(folder_t... folders) {va_list arg_list; va_start(arg_list, folders...);} 调用 QString dir =document_path("DebugX","1111","222","333"); 报错 /home/dev/work/uGround/GlobalApplication.cpp:164: error: too many arguments to function call, expected 2, have 5 报错2: error: ‘va_start’ used in function with fixed args
时间: 2024-03-03 07:47:59 浏览: 232
这个错误是因为 `va_start()` 函数只能用于可变参数列表的函数,而 `document_path()` 函数定义中并没有可变参数列表。因此,你不能在 `document_path()` 函数中使用 `va_start()` 函数。
解决这个问题的方法是将 `document_path()` 函数定义改为可变参数列表函数。具体来说,你可以使用 C++11 中的新特性 `std::initializer_list` 来实现可变参数列表。下面是修改后的代码:
```cpp
template<typename... folder_t>
QString GlobalApplication::document_path(folder_t... folders)
{
QStringList paths{folders...};
QString dir = QCoreApplication::applicationDirPath();
for (const QString& path : paths) {
dir = QDir(dir).filePath(path);
}
return dir;
}
```
然后,你可以像这样调用 `document_path()` 函数:
```cpp
QString dir = document_path("DebugX", "1111", "222", "333");
```
这样就不会再出现你遇到的错误了。
相关问题
用C++代码实现拓扑排序template <typename T, typename WGT_T> std::vector<typename std::graf<T, WGT_T>::size_type> topsort(const std::graf<T, WGT_T>& g)
### 回答1:
以下是用C++代码实现拓扑排序的函数:
```c++
template <typename T, typename WGT_T>
std::vector<typename std::graf<T, WGT_T>::size_type> topsort(const std::graf<T, WGT_T>& g) {
std::vector<typename std::graf<T, WGT_T>::size_type> order;
std::queue<typename std::graf<T, WGT_T>::size_type> q;
std::vector<typename std::graf<T, WGT_T>::size_type> in_degree(g.num_vertices(), 0);
for (typename std::graf<T, WGT_T>::size_type i = 0; i < g.num_vertices(); ++i) {
for (auto& e : g.adj_list(i)) {
++in_degree[e.to()];
}
}
for (typename std::graf<T, WGT_T>::size_type i = 0; i < g.num_vertices(); ++i) {
if (in_degree[i] == 0) {
q.push(i);
}
}
while (!q.empty()) {
typename std::graf<T, WGT_T>::size_type u = q.front();
q.pop();
order.push_back(u);
for (auto& e : g.adj_list(u)) {
--in_degree[e.to()];
if (in_degree[e.to()] == 0) {
q.push(e.to());
}
}
}
return order;
}
```
该函数的输入参数为一个有向图 `g`,返回值为一个顶点序列,表示拓扑排序后的顶点访问顺序。算法思路如下:
1. 统计每个顶点的入度。遍历每个顶点的邻接表,将邻接表中每个顶点的入度加1。
2. 将所有入度为0的顶点入队列。
3. 取出队列的第一个顶点,并将其加入拓扑排序结果序列中。
4. 遍历该顶点的邻接表,将邻接表中每个顶点的入度减1。如果减完之后某个顶点的入度变为0,则将该顶点入队列。
5. 重复步骤3和4,直到队列为空。
时间复杂度为 $O(V+E)$,其中 $V$ 是顶点数,$E$ 是边数。
### 回答2:
拓扑排序是一种用于有向图的算法,将图中的顶点按照一种线性顺序进行排序。在拓扑排序中,如果图中存在从顶点 A 到顶点 B 的有向边,那么在排序结果中,顶点 A 一定在顶点 B 之前。
下面是用 C++ 代码实现拓扑排序的示例:
```cpp
#include <iostream>
#include <vector>
#include <queue>
template <typename T>
std::vector<T> topsort(const std::vector<std::vector<T>>& graph) {
std::vector<T> sortedResult;
std::vector<int> inDegree(graph.size(), 0);
std::queue<T> zeroInDegreeQueue;
// 计算每个顶点的入度
for (const auto& adjacentNodes : graph) {
for (const auto& node : adjacentNodes) {
inDegree[node]++;
}
}
// 将入度为 0 的顶点加入队列
for (int i = 0; i < inDegree.size(); i++) {
if (inDegree[i] == 0) {
zeroInDegreeQueue.push(i);
}
}
// 拓扑排序主循环
while (!zeroInDegreeQueue.empty()) {
T currentNode = zeroInDegreeQueue.front();
zeroInDegreeQueue.pop();
sortedResult.push_back(currentNode);
// 将所有与当前顶点相邻的顶点入度减 1
for (const auto& node : graph[currentNode]) {
inDegree[node]--;
// 如果某个顶点的入度降为 0,则将其加入队列
if (inDegree[node] == 0) {
zeroInDegreeQueue.push(node);
}
}
}
// 如果排序后的结果包含图中所有顶点,则返回排序结果,否则返回空数组表示有环
if (sortedResult.size() == graph.size()) {
return sortedResult;
} else {
return std::vector<T>();
}
}
int main() {
// 创建一个有向图
std::vector<std::vector<int>> graph = {
{1, 2}, // 0 -> 1, 0 -> 2
{2, 3}, // 1 -> 2, 1 -> 3
{3}, // 2 -> 3
{4}, // 3 -> 4
{5}, // 4 -> 5
{5} // 5 -> 5 (自环)
};
// 调用拓扑排序函数
std::vector<int> sortedResult = topsort(graph);
// 输出排序结果
if (sortedResult.empty()) {
std::cout << "The graph contains a cycle." << std::endl;
} else {
std::cout << "Topological Sort Result:";
for (const auto& node : sortedResult) {
std::cout << " " << node;
}
std::cout << std::endl;
}
return 0;
}
```
以上代码使用邻接表表示有向图,并使用队列实现拓扑排序算法。首先计算每个顶点的入度,将入度为 0 的顶点加入队列,并在主循环中不断处理队列中的顶点,将其邻接顶点的入度减 1。最后,如果排序后的顶点数与图中的顶点数相同,则返回排序结果;否则,说明存在环,返回空数组。
示例中的有向图中包含了一个自环(5 -> 5),即一个顶点指向自己。因为拓扑排序要求没有环,所以自环会导致拓扑排序无法进行,最后的结果会返回一个空数组。
### 回答3:
拓扑排序是一种用于有向无环图(DAG)的排序算法。在拓扑排序中,将图中的节点按照一种线性顺序进行排序,使得对于任意的边 (u, v),节点 u 在节点 v 之前。
下面是C++代码实现拓扑排序的模板函数:
```cpp
template <typename T, typename WGT_T>
std::vector<typename std::graf<T, WGT_T>::size_type> topsort(const std::graf<T, WGT_T>& g) {
std::vector<typename std::graf<T, WGT_T>::size_type> result; // 存储拓扑排序的结果
std::queue<typename std::graf<T, WGT_T>::size_type> q; // 存储入度为0的节点
// 统计每个节点的入度
std::vector<typename std::graf<T, WGT_T>::size_type> in_degree(g.num_vertices(), 0);
for (typename std::graf<T, WGT_T>::size_type u = 0; u < g.num_vertices(); ++u) {
for (auto v : g.adjacency_list(u)) {
++in_degree[v];
}
}
// 将入度为0的节点入队列
for (typename std::graf<T, WGT_T>::size_type u = 0; u < g.num_vertices(); ++u) {
if (in_degree[u] == 0) {
q.push(u);
}
}
// 循环处理入度为0的节点
while (!q.empty()) {
typename std::graf<T, WGT_T>::size_type u = q.front();
q.pop();
result.push_back(u);
// 将所有u指向的节点的入度减1,并将入度减为0的节点入队列
for (auto v : g.adjacency_list(u)) {
--in_degree[v];
if (in_degree[v] == 0) {
q.push(v);
}
}
}
// 如果结果集合的大小不等于节点的数量,则说明图中存在环路
if (result.size() != g.num_vertices()) {
result.clear(); // 清空结果
throw std::runtime_error("Graph contains a cycle");
}
return result;
}
```
这个函数使用了队列来存储入度为0的节点。首先,统计每个节点的入度,然后将入度为0的节点入队列。然后,循环处理队列中的节点,将结果放入拓扑排序的结果集合中,并将所有从该节点出发的边的终点的入度减1。如果结果集合的大小不等于节点的数量,则说明图中存在环路,此时会抛出一个异常。
这个函数的时间复杂度是O(V + E),其中V是节点的数量,E是边的数量。
用C++代码写拓扑排序template <typename T, typename WGT_T> std::vector<typename DASS::graf<T, WGT_T>::size_type> topsort(const DASS::graf<T, WGT_T>& g)
以下是用C++实现拓扑排序的代码:
```c++
#include <iostream>
#include <vector>
#include <queue>
template <typename T, typename WGT_T>
std::vector<typename DASS::graf<T, WGT_T>::size_type> topsort(const DASS::graf<T, WGT_T>& g) {
// 初始化入度为 0 的结点队列
std::queue<typename DASS::graf<T, WGT_T>::size_type> q;
std::vector<typename DASS::graf<T, WGT_T>::size_type> in_degree(g.size(), 0);
for (typename DASS::graf<T, WGT_T>::size_type u = 0; u < g.size(); ++u) {
for (const auto& e : g[u]) {
++in_degree[e.v];
}
}
for (typename DASS::graf<T, WGT_T>::size_type u = 0; u < g.size(); ++u) {
if (in_degree[u] == 0) {
q.push(u);
}
}
// 执行拓扑排序
std::vector<typename DASS::graf<T, WGT_T>::size_type> order;
while (!q.empty()) {
typename DASS::graf<T, WGT_T>::size_type u = q.front();
q.pop();
order.push_back(u);
for (const auto& e : g[u]) {
--in_degree[e.v];
if (in_degree[e.v] == 0) {
q.push(e.v);
}
}
}
// 如果存在环,则说明无法进行拓扑排序
if (order.size() != g.size()) {
throw std::runtime_error("The graph contains a cycle");
}
return order;
}
```
使用方法如下:
```c++
DASS::graf<int, int> g(6);
g[0].emplace_back(1, 1);
g[0].emplace_back(2, 1);
g[1].emplace_back(3, 1);
g[2].emplace_back(3, 1);
g[2].emplace_back(4, 1);
g[3].emplace_back(5, 1);
g[4].emplace_back(5, 1);
std::vector<DASS::graf<int, int>::size_type> order = topsort(g);
for (auto u : order) {
std::cout << u << " ";
}
// 输出:0 2 1 4 3 5
```
上述代码中,我们使用了一个队列来存储入度为 0 的结点,然后依次访问队列中的结点并将其从图中删除。如果存在环,则说明无法进行拓扑排序,我们在最后抛出了一个运行时错误。
阅读全文