与函子基类的模棱两可的超负荷
Ambiguous overload with functor base classes
我试图编写与 overload
struct相同的代码。http://en.cppreference.com/w/cpp/utility/variant/variant/visit并将其扩展到功能也是如此。
这是代码https://wandbox.org/permlink/5z2jsejoewkgopex reproded
#include <utility>
#include <type_traits>
#include <cassert>
#include <string>
namespace {
template <typename Func>
class OverloadFuncImpl : public Func {
public:
template <typename F>
explicit OverloadFuncImpl(F&& f) : Func{std::forward<F>(f)} {}
using Func::operator();
};
template <typename ReturnType, typename... Args>
class OverloadFuncImpl<ReturnType (*) (Args...)> {
public:
template <typename F>
explicit OverloadFuncImpl(F&& f) : func{std::forward<F>(f)} {}
ReturnType operator()(Args... args) {
return this->func(args...);
}
private:
ReturnType (*func) (Args...);
};
template <typename... Funcs>
class Overload;
template <typename Func, typename... Funcs>
class Overload<Func, Funcs...>
: public OverloadFuncImpl<Func>,
public Overload<Funcs...> {
public:
template <typename F, typename... Fs>
explicit Overload(F&& f, Fs&&... fs)
: OverloadFuncImpl<Func>{std::forward<F>(f)},
Overload<Funcs...>{std::forward<Fs>(fs)...} {}
using OverloadFuncImpl<Func>::operator();
using Overload<Funcs...>::operator();
};
template <typename Func>
class Overload<Func> : public OverloadFuncImpl<Func> {
public:
template <typename F>
explicit Overload(F&& f) : OverloadFuncImpl<Func>{std::forward<F>(f)} {}
using OverloadFuncImpl<Func>::operator();
};
}
template <typename... Funcs>
auto make_overload(Funcs&&... funcs) {
return Overload<std::decay_t<Funcs>...>{std::forward<Funcs>(funcs)...};
}
char foo(char ch) {
return ch;
}
int main() {
auto overloaded = make_overload(
[&](int integer) { return integer; },
[&](std::string str) { return str; },
[&](double d) { return d; },
foo);
assert(overloaded("something") == "something");
assert(overloaded(1.1) == 1.1);
return 0;
}
这是我得到的错误
In file included from /opt/wandbox/gcc-7.2.0/include/c++/7.2.0/cassert:44:0,
from prog.cc:3:
prog.cc: In function 'int main()':
prog.cc:66:26: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
assert(overloaded(1.1) == 1.1);
^
prog.cc:62:21: note: candidate 1: main()::<lambda(double)>
[&](double d) { return d; },
^
prog.cc:19:20: note: candidate 2: ReturnType {anonymous}::OverloadFuncImpl<ReturnType (*)(Args ...)>::operator()(Args ...) [with ReturnType = char; Args = {char}]
ReturnType operator()(Args... args) {
^~~~~~~~
编译器和标准解释有几个问题,使得有必要一一一次地导入operator()
。但是,OverloadFuncImpl
功能专业的operator()
似乎无法正确导入using
。
请注意,当我不使用OverloadFuncImpl
或排除OverloadFuncImpl
的功能部分专业化时,上面的代码正常工作。
我已经让此代码使用了解决方法,但是我只是想知道为什么上面的代码不起作用。我似乎无法弄清楚...为什么当我导入所有基类的所有operator()
时。仍然有模棱两可的超负荷问题?
我试图在较小的上下文中重现错误,但无法...
ReturnType operator()(Args... args) const {
// ^^^^^
return this->func(args...);
}
有效地,有效集合中的相关候选人是
char operator()(char);
double operator()(double) const;
在非const
对象上调用类型double
的参数。
隐式对象参数上的第一个胜利;第二个胜利是实际函数参数。随之而来的歧义。
相关文章:
- "Inverse SFINAE"避免模棱两可的过载
- 操作员C++的模棱两可的过载
- 模棱两可的重载模板
- 调用重载的"<大括号括起来的初始值设定项列表>"对于对来说就足够了是模棱两可的
- 模棱两可的 != reverse_iterator运算符
- SFINAE不能防止模棱两可的操作员过载吗?
- VSCode 说 std::chrono 是模棱两可的,如果运算符<<重载
- 为什么对模板的调用不模棱两可?
- 修复重载运算符的使用'+'模棱两可?
- 为什么同时覆盖全局新运算符和特定于类的运算符不是模棱两可的行为?
- Antlr4 C++访问模棱两可的分支
- 模棱两可的调用 - 模板化函数
- 在SESHAT中,对"元组"的引用是模棱两可的
- C++17 年与 Clang 的模棱两可的部分专业化
- gcc 中的模棱两可的运算符
- 将 NULL 转换为长不是模棱两可吗?
- C++ lambda 模棱两可的调用
- 带有模板的循环缓冲区在Keil MDK5上是模棱两可的错误?
- 与函子基类的模棱两可的超负荷
- C 超负荷分辨率模棱两可-GCC