gpt4 book ai didi

c++ - 没有可行的重载 '=' 用于重载的静态成员函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:42:08 24 4
gpt4 key购买 nike

我有这个简化的代码,它由一个带有静态函数的类组成,存储在 map 中:

#include <iostream>
#include <functional>
#include <map>

class A {
public:
static void f(const std::string &s) { std::cout << s; }
};

std::map<std::string, std::function<void(std::string const &)>> fs;

int main() {
fs["f"] = &A::f;
fs["f"]("hello");
}

这会打印预期的hello

如果我重载 f() 会出现问题:

 static void f(const std::string &s, int c) { while(c-->0) { std::cout << s; } }

这会导致错误:

 error: no viable overloaded '='
fs["f"] = &A::f;
~~~~~~~ ^ ~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/functional:2241:7: note: candidate function not viable: no overload of 'f' matching 'const std::function<void (const std::basic_string<char> &)>' for 1st argument
operator=(const function& __x)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/functional:2259:7: note: candidate function not viable: no overload of 'f' matching 'std::function<void (const std::basic_string<char> &)>' for 1st argument
operator=(function&& __x)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/functional:2273:7: note: candidate function not viable: no overload of 'f' matching 'nullptr_t' for 1st argument
operator=(nullptr_t)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/functional:2302:2: note: candidate template ignored: couldn't infer template argument '_Functor'
operator=(_Functor&& __f)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/functional:2311:2: note: candidate template ignored: couldn't infer template argument '_Functor'
operator=(reference_wrapper<_Functor> __f) noexcept
^

但是,调用这两个函数都有效:

A::f("hello ");
A::f("echo ", 3);

所以,我的问题是:

  1. 如果我不重载 f(),即使 operator= 似乎存在并起作用,为什么这段代码无法编译?
  2. 如何在不给两个函数不同的名称的情况下让它工作?

最佳答案

Why this code not compiling even though the operator= seems to exist and function if I don't overload f()?

因为编译器不知道选择哪个重载。他怎么可能?没有标准可以让他决定哪一个更适合。每个 std::function 都允许分配任意函数对象并且不检查任何 签名。如果您只想保存此特定签名的函数指针,您应该适本地声明 map

How can I get it to work without giving both functions different names?

如前所述,它通过将表达式转换为特定类型的函数指针来工作。

fs["f"] = static_cast<void(*)(std::string const&)>( &A::f );

这样就不会产生歧义;只有一个重载可以将此函数转换为指针类型。
如果这种情况出现得更频繁,则 typedef 可能是可行的。

或者一个小助手类模板:

template <typename... Exact>
struct funptr
{
template <typename R>
constexpr auto operator()(R(*p)(Exact...)) -> decltype(p)
{ return p; }
};

fs["f"] = funptr<std::string const&>()(&A::f);

Demo .

关于c++ - 没有可行的重载 '=' 用于重载的静态成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26809979/

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