【问题标题】:Tempate defined by return value of lambda function由 lambda 函数的返回值定义的模板
【发布时间】:2017-07-30 17:48:48
【问题描述】:

让它成为一个需要这种行为的模板:

template<typename MyActionLambda>
void enumerateChildrenByTag(QDomNodeList& list, const QString& tag, MyActionLambda action )
{
    for(int i = 0; i < list.size(); i++) {
        QDomElement el = list.item(i).firstChildElement(tag);
        while(!el.isNull())
        {
            if( typeid(decltype(action(el))) == typeid(SomeType) )
            {
                    auto res = action(el)
                    // do something with res
            }
            else
                    // do something with action(el)

            el = el.nextSiblingElement(tag);
        }
    }
}

这显然是不可能的,因为它为 lambda 编写的返回类型为 void,因为 if() 的两个分支都应该是合法的。除了将 declspec 作为模板参数的默认值并专门化两个模板之外,是否有更简单的方法来解决此问题?

【问题讨论】:

  • std::result_of 可能有用吗?

标签: c++11 templates lambda declspec


【解决方案1】:

使用 C++17 你可以编写

if constexpr( std::is_same<decltype(action(el)),SomeType>::value )
    auto res = action(el);
else
{ /* do something else */ }

但我认为这种结构使用模板化函数更具可读性,您可以专门针对SomeType:

template<class X>
void someFunction(const X& x) { /* standard case */ }
template<>
void someFunction(const SomeType& x) { /* SomeType case */ }

在你的循环中你只需调用:

for(QDomElement el = list.item(i).firstChildElement(tag);
                !el.isNull(); el = el.nextSiblingElement(tag))
    someFunction(action(el));

【讨论】:

  • 虽然没有 C++17,但不知道 if 语法,是后来的草稿吗?但是让那些适配器函数看起来更简单,谢谢.. 更简单的是我需要让不太雄辩的同事理解代码
猜你喜欢
  • 2020-07-19
  • 1970-01-01
  • 1970-01-01
  • 2021-12-11
  • 1970-01-01
  • 2017-03-02
  • 1970-01-01
  • 2022-10-14
  • 1970-01-01
相关资源
最近更新 更多