首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >只有在一个参数中没有使用std::函数时,模板函数替换才能工作

只有在一个参数中没有使用std::函数时,模板函数替换才能工作
EN

Stack Overflow用户
提问于 2018-09-07 23:35:22
回答 1查看 46关注 0票数 1

我有一个带有两个模板参数的模板函数。

第一个(T)是根据第一个参数的类型推导出来的。第二种方法(ItrT)是利用std::type_traitsT推导出来的。

当我使用ItrT作为参数的类型(参见函数bar)时,所有类型都是隐式推导的,但是当我使用std::function<void(ItrT)>作为参数的类型(参见函数foo)时,只有在完全指定所有模板参数时才能推断正确的类型(即使使用与函数定义完全相同的代码)。可以想象,在模板中使用ItrT不会改变编译器推断模板的能力。

为什么不是这种情况?我需要做些什么,以便隐式地推导出所有的模板参数?

我在用C++17。

代码语言:javascript
复制
template <class T, class ItrT = typename std::iterator_traits<T>::value_type>
auto foo(T iterator, std::function<void(ItrT)> expr) -> void{
}

template <class T, class ItrT = typename std::iterator_traits<T>::value_type>
auto bar(T iterator, ItrT expr) -> void{
}

int main() {
    std::vector<int> vec = {1, 2, 3};

    bar(vec.begin(), 1); // Compiles!

    foo(vec.begin(), [](int) {}); // Failes!

    foo<decltype(vec.begin()),
        std::iterator_traits<decltype(vec.begin())>::value_type>
        (vec.begin(), [](int) {}); // Compiles!
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-08 02:33:41

我猜这里的困惑是关于默认模板参数的角色。

规则不是:尝试推断一个参数。如果扣减失败,则使用默认值(如果提供)。

相反,规则是:如果参数在推导的上下文中,则推导它。如果扣减失败,中止。如果它不是在推导的上下文中,并且没有显式提供,那么使用默认的参数。换句话说,只有在参数既不是在推导的上下文中也没有显式提供的情况下,才会使用默认参数。

在这两个示例中,ItrT都位于推导的上下文中,因此根本不考虑默认的模板参数。两者的区别在于,您可以从lambda中推断出T (只匹配它的类型),但是不能从lambda中推断出function<void(T) -- lambda可以转换为适当的function,但是lambda不是function。模板演绎不进行转换。模板演绎只与模式匹配。

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

https://stackoverflow.com/questions/52230730

复制
相关文章

相似问题

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