簡體   English   中英

由於不兼容的cv限定符而無法編譯

[英]Failed to compile because of incompatible cv-qualifiers

我有兩個模板方法

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接受任意函數對象 ,敷您的來電insert通用拉姆達

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));

直播wandbox示例

遺憾的是,附加的語法樣板是不可避免的。 這可能在將來發生變化,請參閱:

  • N3617旨在通過引入“電梯”操作員來解決這個問題。

  • A. Sutton的P0119通過允許重載集在作為參數傳遞時基本上為你生成“包裝器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));

你可以看到它不是很漂亮。 它可以通過一些更好的模板參數推導來改進,但不是很多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM