尝试写的for_each算法MFC的CMap的算法、for_each、CMap、MFC

2023-09-11 06:54:24 作者:Weirdo(怪人)

是的,我知道我应该做一个迭代器,但我需要这个做得风生水起,写一个正确的迭代器相关的任何VC ++超出令人沮丧。 (这还要为众多其他标准的东西,并且buggering了我的工作量。:()

所以我写了的for_each()算法来处理污秽:

 模板< typename的K,typename的AK,typename的V,类型名AV>
无效的for_each(CMap的< K,AK,V,AV>&安培;容器的std ::功能<无效(AK,AV)>体)
{
    位置POS = container.GetStartPosition();
    而(POS!= NULL)
    {
        AK关键;
        AV值;
        //获取键和值
        集装箱.GetNextAssoc(POS,键,值);
        体(键,值);
    }
}
 

但显然VC ++不能推断出AK和AV的函数模板。这是正常的或者是有VC这又限制++?

修改 这是错误的要求:

  1> D:\项目\清洁\ CV32 \ cvcustombuttoninfo.cpp(113):错误C2784:无效的for_each(CMap的< KEY,ARG_KEY,价值,ARG_VALUE>&安培;,的std ::功能<无效(AK,AV)>):无法推断出模板参数的std ::功能<无效(AK,AV)>从CCVCustomRibbonInfo :: WriteFile的::< lambda_0513c2955d2b7b0197efcf2b0ce9322b>
1> D:\项目\清洁\ CV32 \ cvcustombuttoninfo.cpp(66):看到宣言的for_each的
 
Read the following three passages.Each passage is followed by several questions or unfinished statements.For each of them there

这似乎也发生在GCC 4.9.0与-std = C ++ 11的参数。

 的#include<功能>
模板< typename的T>
无效FN(T(T),的std ::功能<无效(T)>)
{
}

诠释的main()
{
  INT I;
  FN(I,[](int i)以{});
  返回0;
}
 

[DEMO]

而G ++错误:

  /tmp/gcc-explorer-compiler115110-34-1cr9oud/example.cpp:在函数'诠释的main():
11:错误:没有匹配函数调用FN(INT和放大器;,主()::)
FN(I,[](int i)以{});
^
11:注:候选人是:
4:注意:模板无效FN(T,的std ::功能)
无效FN(T(T),的std ::功能<无效(T)>)
^
4:注意:模板参数推导/置换失败:
11:注意:主要()::'不是从'的std ::功能派生
FN(I,[](int i)以{});
^
编译失败
 

解决方案

C ++ lambda表达式不具有相同的类型作为的std ::功能具有相同签名。这就是为什么模板参数推导失败 - 它的工作原理与具体类型,更多或更少。转换使用模板实参推演的不考虑。你不希望使用的std ::功能在你的模板参数。要强制签名,你可以检查 Func键可转化成的std ::功能<无效(AK,AV)>

 模板< typename的K,typename的AK,typename的V,typename的AV,typename的函数功能,类型名=的std :: enable_if_t<的std :: is_convertible< FUNC键的std ::功能<无效(AK,AV)>> ::值GT; >
无效的for_each(CMap的< K,AK,V,AV>&安培;容器,Func键体)
{
    位置POS = container.GetStartPosition();
    而(POS!= NULL)
    {
        AK关键;
        AV值;
        //获取键和值
        集装箱.GetNextAssoc(POS,键,值);
        体(键,值);
    }
}
 

Yeah, I know that I should make an iterator, but I need this done fast and writing a proper iterator for anything related to VC++ is beyond frustrating. (This also goes for many other standard things and is buggering up my work load. :( )

So I wrote a for_each() algorithm to deal with the nastiness:

template <typename K, typename AK, typename V, typename AV>
void for_each(CMap<K, AK, V, AV>& container, std::function<void(AK, AV)> body)
{
    POSITION pos = container.GetStartPosition();
    while (pos != NULL)
    {
        AK key;
        AV value;
        // Get key and value
        container .GetNextAssoc(pos, key, value);
        body(key, value);
    }
}

But apparently VC++ can't deduce AK and AV for the function template. Is this normal or is this yet another limitation of VC++?

Edit Here is the errors as requested:

1>d:\projects\clean\cv32\cvcustombuttoninfo.cpp(113): error C2784: 'void for_each(CMap<KEY,ARG_KEY,VALUE,ARG_VALUE> &,std::function<void(AK,AV)>)' : could not deduce template argument for 'std::function<void(AK,AV)>' from 'CCVCustomRibbonInfo::WriteFile::<lambda_0513c2955d2b7b0197efcf2b0ce9322b>'
1>          d:\projects\clean\cv32\cvcustombuttoninfo.cpp(66) : see declaration of 'for_each'

This seems to also happen on gcc 4.9.0 with -std=c++11 parameter.

#include <functional>
template <typename T>
void fn(T t, std::function<void(T)>)
{
}

int main()
{
  int i;
  fn(i, [](int i){});
  return 0;
}

[DEMO]

And the g++ errors:

/tmp/gcc-explorer-compiler115110-34-1cr9oud/example.cpp: In function 'int main()':
11 : error: no matching function for call to 'fn(int&, main()::)'
fn(i, [](int i){});
^
11 : note: candidate is:
4 : note: template void fn(T, std::function)
void fn(T t, std::function<void(T)>)
^
4 : note: template argument deduction/substitution failed:
11 : note: 'main()::' is not derived from 'std::function'
fn(i, [](int i){});
^
Compilation failed

解决方案

C++ lambdas don't have the same type as an std::function with the same signature. This is why the template argument deduction fails - it works with exact types, more or less. Conversions are not considered using template argument deduction. You don't want to use an std::function in your template argument. To force signature, you can check that Func is convertible to an std::function<void(AK, AV)>.

template <typename K, typename AK, typename V, typename AV, typename Func, typename = std::enable_if_t<std::is_convertible<Func, std::function<void(AK, AV)>>::value> >
void for_each(CMap<K, AK, V, AV>& container, Func body)
{
    POSITION pos = container.GetStartPosition();
    while (pos != NULL)
    {
        AK key;
        AV value;
        // Get key and value
        container .GetNextAssoc(pos, key, value);
        body(key, value);
    }
}

 
精彩推荐
图片推荐