gpt4 book ai didi

c++ - 为什么 C++ 将此视为不明确的函数引用

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:17:12 25 4
gpt4 key购买 nike

为什么我的编译器会认为以下 GetLength 函数指针不明确
伪代码:

size_t GetLength(char*);
size_t GetLength(wchar_t*);
struct ITEM { };
double GetLength(ITEM*);

CString GetInfo(ITEM * item, std::function<double (ITEM*)> fn)
{
... omitted for clarity
}

ITEM * item = new ITEM;
cout << GetInfo(item, GetLength); // <- ambiguous error

GetInfo 只允许双重返回 + ITEM* 参数模式。那么为什么要考虑(而不是丢弃)GetLength 的两个基于字符串的变体?

最佳答案

std::function<...> 的构造函数是模板化的,因为它必须能够支持任何类似函数的输入类型。没有单一的类型可以尝试推导出来,所以你的重载都是可以构造的;直到稍后的编译才会出现类型不匹配的错误。

你可以这样做:

GetInfo(item, static_cast<double(*)(ITEM*)>(GetLength));

显式丢弃其他重载。


换句话说,这是行不通的原因:

void foo(int);
void foo(void*);

struct bar
{
template <typename T>
bar(T f)
{
f(5);
}
};

bar b(foo);

即使 bar 的构造函数主体仅适用于 void foo(int) ,它希望支持 f(5) 的任何功能将工作,因此参数类型被模板化。这允许任何函数在那个地方工作,这意味着编译器无法推断出要使用的单个最佳重载。


我认为一种语言级别的解决方案是让重载集本身成为一个仿函数。也就是说,给定:

void foo(int);
void foo(void*);

template <typename T>
double foo(int, T);

命名 foo (如 bar(foo) 或什至只是 foo(5) )导致这种类型的实例:

struct __foo_overload_set // internal
{
// forwarders
void operator()(int __arg0) const
{
// where __foo0 is the zeroth overload, etc...
return __foo0(__arg0);
}

void operator()(void* __arg0) const
{
return __foo1(__arg0);
}

template <typename __Arg1>
double operator()(int __arg0, __Arg1&& __arg1) const
{
return __foo2(__arg0, std::forward<__Arg1>(__arg1));
}

// converters
typedef void(*__foo0_type)(int);

operator __foo0_type() const
{
return __foo0;
}

typedef void(*__foo1_type)(void*);

operator __foo1_type() const
{
return __foo1;
}

template <typename T>
struct __foo2_type
{
typedef void(*type)(int, T);
};

template <typename T>
operator typename __foo2_type<T>::type() const
{
return __foo2;
}
};

它本身是可调用的,在我们想要的上下文中编译。 (据我所知,它不会引入任何不存在的歧义,尽管它完全未经测试。)

关于c++ - 为什么 C++ 将此视为不明确的函数引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8156812/

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