当前位置: 首页 > 知识库问答 >
问题:

当使用enable_if和SFINAE时,函数参数类型推断(std容器,例如vector)失败

田英卓
2023-03-14

我好像不知道我错在哪了。请参阅https://ideone.com/wkszsn

我试图创建一个函数,该函数只有在其参数是某种模板化类时才存在,为迭代器公开一个typedef。

在非条件情况下,函数看起来如下所示:

template<template <class, class> class C, class T, class A>
void DoSomething(C<T,A>& val)
{
    T* pT;
    cout << "did something!\n";
}

在本例中,类型扣除对此代码段很有效:

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

好的。现在我想对参数进行类型推导,并使container类公开typedef迭代器。使用herb sutter gotw sfinae模式,我创建了:

template<class T> struct supports_iteration
{ 
private:
    typedef char yes[1];
    typedef char no[2];
    template <class C> static yes& foo(typename C::iterator*);
    template <class C> static no& foo(...);
public:
    static constexpr bool value = sizeof(foo<T>(0)) == sizeof(yes);
};

好的,使用这个,我现在可以检测iterator是否公开了:

vector<int> v{1,2,3,4,5};
DoSomething(v);
cout << "vector<int> supports_iteration? " << 
    boolalpha << supports_iteration<decltype(v)>::value << "!" << endl;

工作良好,输出:

did something!
vector<int> supports_iteration? true!

好了,现在我想使用enable_if升级DoSomething(),如下所示:

template<template <class, class> class C, class T, class A>
void DoSomethingSmartly(
    typename std::enable_if<
        supports_iteration<
            C<T,A>
        >::value
    >::type& val)
{
    T* pT;
    cout << "did something smartly!\n";
}

但这不管用。我得到了

prog.cpp:在函数“int main()”中:prog.cpp:44:22:错误:调用“DoSomethingSmartly(std::Vector&)”DoSomethingSmartly(v)没有匹配的函数;//-失败!!^prog.cpp:26:6:注意:候选:template class C,class T,class A>void DoSomethingSmartly(typename std::enable_if>::value>::type&)void DoSomethingSmartly(^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)

我做错了什么?

共有1个答案

景星光
2023-03-14

在您的尝试中,CTa处于不可推断的上下文中(在traits ::type T中处于不可推断的上下文中),您可以在返回类型上使用enable_if:

template<template <class, class> class C, class T, class A>
typename std::enable_if<supports_iteration<C<T,A>>::value>::type
DoSomethingSmartly(C<T, A>& val)
{
   // ...
}
 类似资料:
  • C 14将具有返回类型可根据返回值推断的函数。 我是否可以将这种行为应用于使用enable_if作为SFINAE按返回类型惯用法的函数? 例如,让我们考虑以下两个函数: 如您所见,使用SFINAE by return-type习惯用法选择了正确的函数。然而,这些都是空洞函数。的第二个参数默认设置为。这是一样的: 我能对这两个函数做些什么,让它们的返回类型由返回值推断出来吗? gcc 4.8.2(使

  • 我最近一直在摆弄泛型类型,在编写一个函数时,我不得不使用函数中的一个参数来确定返回类型。 大致来说,我想做以下几点: 在Typescript平台上运行上述代码时,我遇到以下错误消息: 类型“number”不能分配给类型“ReturnType”“number”可分配给“ReturnType”类型的约束,但“ReturnType”可以用约束“string | number”的不同子类型实例化。(232

  • 我正在构建一些输入检查器,需要为整数和/或双精度设置特定的函数(例如,“iPrime”应该只适用于整数)。 如果我使用作为参数,它工作得很好: 但如果我将其用作模板参数(如上所示)http://en.cppreference.com/w/cpp/types/enable_if ) 那么我有以下错误: 我不知道第二个版本出了什么问题。

  • 前几天我问了一个关于嵌套向量的非常类似的问题,但我遇到了另一个让我难堪的问题。我需要在编译时获取嵌套向量的最内层类型,以便将其作为模板参数传递。 例如,如果我有这个嵌套向量: 我需要一种方法来提取,这样我就可以调用一个函数,它需要一个嵌套的向量,并对这样的元素工作: 除了catch之外,这个函数应该能够处理包含任何类型的任何深度的嵌套向量。当我调用时,我希望自动为我推导出内部类型。 所以也许电话看

  • 我发现了和类型推导的以下行为,这对我来说是意想不到的: 中的两行都会导致错误: 没有函数模板“stdfunc_test”的实例与参数列表匹配 尝试在Visual Studio 2015中编译时。 为什么类型演绎不从函数类型中演绎模板类型,有没有变通方法?

  • 我使用一个密封类从网络返回数据。但是当我在构建这个项目时,我得到了以下错误 类型推断失败:没有足够的信息来推断参数T in fun error(错误消息:String,错误:Throwable):状态请明确指定它。 我错过了什么? 这是代码