gpt4 book ai didi

c++ - 由于不兼容的 cv 限定符而无法编译

转载 作者:太空狗 更新时间:2023-10-29 20:21:33 24 4
gpt4 key购买 nike

我有两个模板方法

template <typename T, typename Ret, typename ...Args>
Ret apply(T* object, Ret(T::*method)(Args...), Args&& ...args) {
return (object->*method)(std::forward(args)...);
};

template <typename T, typename Ret, typename ...Args>
Ret apply(T* object, Ret(T::*method)(Args...) const, Args&& ...args) {
return (object->*method)(std::forward(args)...);
};

我的目的是在这些args上应用 T 类的成员方法

这是我的测试代码:

int main() {
using map_type = std::map<std::string, int>;
map_type map;
map.insert(std::make_pair("a", 1));
std::cout << "Map size: " << apply(&map, &map_type::size) << std::endl; //this code work
apply(&map, &map_type::insert, std::make_pair("a", 1)); //failed to compile

return 0;
}

这是编译器错误信息:

    test.cpp: In function ‘int main()’:
test.cpp:61:58: error: no matching function for call to ‘apply(map_type*, <unresolved overloaded function type>, std::pair<const char*, int>)’
apply(&map, &map_type::insert, std::make_pair("a", 1));
^
test.cpp:11:5: note: candidate: template<class T, class Ret, class ... Args> Ret apply(T*, Ret (T::*)(Args ...), Args&& ...)
Ret apply(T* object, Ret(T::*method)(Args...), Args&& ...args) {
^~~~~
test.cpp:11:5: note: template argument deduction/substitution failed:
test.cpp:61:58: note: couldn't deduce template parameter ‘Ret’
apply(&map, &map_type::insert, std::make_pair("a", 1));

最佳答案

std::map::insert是一个重载函数。除非您明确指定您感兴趣的重载,否则您不能获取它的地址 - 否则编译器怎么知道?

解决问题的最简单方法是让 apply 接受任意 function object 并将对 insert 的调用包装在 通用 lambda

template <typename F, typename ...Args>
decltype(auto) apply(F f, Args&& ...args) {
return f(std::forward<Args>(args)...);
};

用法:

::apply([&](auto&&... xs) -> decltype(auto)
{
return map.insert(std::forward<decltype(xs)>(xs)...);
}, std::make_pair("a", 1));

live wandbox example

不幸的是,额外的语法样板是无法避免的。这在未来可能会改变,请参阅:

  • N3617旨在通过引入“提升”运算符来解决这个问题。

  • P0119 A. Sutton 以不同的方式解决了这个问题,它允许重载集在作为参数传递时基本上为您生成“包装器 lambda”。

不过,我不确定上述提案是否支持重载成员函数


您也可以通过在调用方明确指定您感兴趣的重载来使用您的原始解决方案:

::apply<map_type, std::pair<typename map_type::iterator, bool>,
std::pair<const char* const, int>>(
&map, &map_type::insert<std::pair<const char* const, int>>,
std::make_pair("a", 1));

如您所见,它不是很漂亮。它可能可以通过一些更好的模板参数推导来改进,但不会太大。

关于c++ - 由于不兼容的 cv 限定符而无法编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43588742/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com