我似乎无法弄清楚我要去哪里。
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);


好。所以现在我要键入-ducuce我的参数,如果容器类公开了typedef迭代器,则启用enable_if。我使用草药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);
};


好的,因此使用此命令,我现在可以检测是否公开了迭代器:

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:注意:候选:模板类C,类T,类A> void DoSomethingSmartly(typename std :: enable_if> :: value> :: type&)
 无效DoSomethingSmartly(
      ^ ~~~~~~~~~~~~~~~~~
prog.cpp:26:6:注意:模板参数推导/替换失败:
prog.cpp:44:22:注意:无法推断出模板参数“模板类C”
  DoSomethingSmartly(v); //-失败!

我究竟做错了什么?

最佳答案

在尝试CTA在不可推论的上下文中(在traits<T>::typeT在不可推论的上下文中),您可以在返回类型上使用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)
{
   // ...
}

10-08 08:54