5

我想创建一个模板化函数,它对 const 和非 const 数据的工作方式相同,只是它根据需要返回一个 const 或非 const 指针。

例如,我想返回一个指向容器中匹配元素的指针:

template <class Container, class Pred>
typename Container::value_type* getValuePtrIf(Container& c, Pred pred)
{
    auto it=std::find_if(c.begin(), c.end(), pred);
    return (it!=c.end()) ? &(*it) : nullptr;
}

但是,我无法为 const 和非常量调用构建它。如果我在声明中省略了 const,Container& c那么它就不能返回一个 const 指针,但是如果我更改为,const Container& c那么我可以返回一个 const 指针,但是非 const 情况不会建立。

有没有一种方法来定义它,以便将其const解释为Container模板参数的一部分,以便我只需要定义这个函数的一个版本?

4

2 回答 2

6

从代码来看,您的编译器似乎支持 C++11。然后你可能也可以使用decltype和尾随返回类型:

template <class Container, class Pred>
auto getValuePtrIf(Container& c, Pred pred) -> decltype(&*std::begin(c))
{
    auto it=std::find_if(std::begin(c), std::end(c), pred);
    return (it!=std::end(c)) ? &(*it) : nullptr;
}

it将为您提供的任何类型std::begin(c)(iteratorconst_iterator),因此 of 的类型与 of&(*it)相同decltype(&*std::begin(c))

于 2013-11-11T13:04:46.310 回答
-1

最简单的就是定义两个模板,让编译器找到最佳匹配

template <class Container, class Pred>
typename const Container::value_type* getValuePtrIf(const Container& c, Pred pred)
{
    auto it=std::find_if(c.begin(), c.end(), pred);
    return (it!=c.end()) ? &(*it) : nullptr;
}
template <class Container, class Pred>
typename Container::value_type* getValuePtrIf(Container& c, Pred pred)
{
    auto it=std::find_if(c.begin(), c.end(), pred);
    return (it!=c.end()) ? &(*it) : nullptr;
}

如果您因维护问题而反对重复代码(值得反对),您可以尝试以下操作:

template <class Container, class Pred>
typename const Container::value_type* getValuePtrIf(const Container& c, Pred pred)
{
    auto it=std::find_if(c.begin(), c.end(), pred);
    return (it!=c.end()) ? &(*it) : nullptr;
}
template <class Container, class Pred>
typename Container::value_type* getValuePtrIf(Container& c, Pred pred)
{
    return const_cast<Container::value_type*>(
        getValuePtrIf(const_cast<const Container &>( c ), pred)
    );
}

如果是我,我也会用 const Pred & pred 替换 Pred)

罗伯特·拉米

于 2013-11-11T16:16:49.610 回答