首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >调试模板推演失败

调试模板推演失败
EN

Stack Overflow用户
提问于 2016-06-09 21:30:17
回答 3查看 491关注 0票数 7

为什么以下命令不起作用:

代码语言:javascript
复制
std::string fn(int i)
{
        sleep(i); // number of seconds to sleep for
        std::cout << "Exiting after pausing " << i << " seconds\n";
        return std::to_string(i+1);
}

template<typename T, typename U>
int simult( std::function<T(U)> f, std::vector<U> args)
{
        return 666;
}


int main()
{

        std::vector<int> args { 6, 5, 7 };        
        int r = simult(fn, args);
}

函数模拟显然是不完整的:我只是想在这个阶段获得一些要编译的东西。其思想是,您提供一个函数和一个args列表,simult将使用线程调用将args分段应用于f。

在这个阶段,我只是想弄清楚编译问题。

代码语言:javascript
复制
simult.cc: In function ‘int main()’:
simult.cc:43:25: error: no matching function for call to ‘simult(std::__cxx11::string (&)(int), std::vector<int>&)’
  int r = simult(fn, args);
                         ^
simult.cc:23:5: note: candidate: template<class T, class U> int simult(std::function<T(U)>, std::vector<U>)
 int simult( std::function<T(U)> f, std::vector<U> args)
     ^~~~~~
simult.cc:23:5: note:   template argument deduction/substitution failed:
simult.cc:43:25: note:   mismatched types ‘std::function<T(U)>’ and ‘std::__cxx11::string (*)(int) {aka std::__cxx11::basic_string<char> (*)(int)}’
  int r = simult(fn, args);
                         ^
EN

回答 3

Stack Overflow用户

发布于 2016-06-09 21:39:17

模板推导不会触发隐式转换。尽管函数(指针)类型是可转换的std::function,但这种转换从来不是模板替换的一部分。

您必须构造std::function并将其传递给simlut

代码语言:javascript
复制
int r = simult(std::function<std::string (int)>(fn), args);
票数 1
EN

Stack Overflow用户

发布于 2016-06-09 21:47:09

由于在模板参数推导中没有考虑用户定义的转换,所以它不起作用。

您可以通过显式提供模板参数来帮助编译器,并按如下方式调用simult

代码语言:javascript
复制
int r = simult<std::string, int>(fn, args);

或者,您可以使用decltype来解决这个问题,如下所示:

代码语言:javascript
复制
std::string fn(int i) {
  return std::to_string(i + 1);
}

template<typename T, typename U>
int simult_impl(std::function<T(U)> f, std::vector<U> const &args) {
  return 666;
}

template<typename F, typename U>
int simult(F f, std::vector<U> const &args) {
  return simult_impl<decltype(f(args[0])), U>(f, args);
}

编辑:

如果您希望在编译器支持C++14的情况下返回std::vector<T>,则可以按如下方式进行更改:

代码语言:javascript
复制
template<typename T, typename U>
std::vector<T> simult_impl(std::function<T(U)> f, std::vector<U> const &args) {
  return std::vector<T>(10, T{"666"});
}

template<typename F, typename U>
auto simult(F f, std::vector<U> const &args) {
  return simult_impl<decltype(f(args[0])), U>(f, args);
}
票数 1
EN

Stack Overflow用户

发布于 2016-06-09 22:27:09

使用@SergeyA的建议,我能够想出工作代码,现在作为一个完整的例子:

代码语言:javascript
复制
#include <functional>
#include <iostream>
#include <string>
#include <future>
#include <thread>
#include <vector>

#include <unistd.h> // for sleep. Not needed generally

// declare a function that does what you want
std::string fn(int i)
{
        sleep(i); // number of seconds to sleep for
        std::cout << "Exiting after pausing " << i << " seconds\n";
        return std::to_string(i+1);
}



template<typename T, typename U>
std::vector<T> simult(std::function<T(U)> func, std::vector<U> const &args)
{
        std::vector<std::future<T>> fs;
        for(auto& a:args) fs.push_back(std::async(func, a));

        std::vector<T> results;
        for(auto &f:fs) results.push_back(f.get());
        return results;
}



int main()
{
        std::vector<int> args { 6, 5, 7 };
        std::vector<std::string> results = simult(std::function<std::string (int)>(fn), args);
        std::cout << "Results are:\n";
        for(auto&r:results) std::cout << r << "\n"; //results are returned in correct order
        return 0;
}

编译:

代码语言:javascript
复制
g++ simult.cc -o simult -lpthread

运行:

代码语言:javascript
复制
time -p simult
Exiting after pausing 5 seconds
Exiting after pausing 6 seconds
Exiting after pausing 7 seconds
Results are:
7
6
8
real 7.00
user 0.00
sys 0.00

我仍然有点困惑,为什么C++不能自己推断函数的类型,但我想最重要的是它可以工作。对我来说,调用者似乎是不必要的冗长。

编辑:在function simult()中,将std::string实例替换为T

编辑:已将std::vector<U> args更改为std::vector<U> const &args

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37727432

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档