c++ - 转换重载函数不明确

标签 c++ gcc type-conversion function-pointers overloading

我有一个问题,即创建指向重载函数的函数指针会导致 g++ 4.7 和 g++ 4.8 上的编译错误,但在 g++ 4.4、g++ 4.6 或 clang++ 3.2(可能还有 VS2010)上不会。

我在谷歌上搜索了一下,想知道问题出在 g++ 还是我的代码上,但我仍然无法决定。 适用于函数指针转换的重载决议规则与适用于函数调用的重载决议规则是否不同?

这是演示问题的最小化代码:

template < class T >
struct Dummy {
    typedef T value_type;
    value_type value;
};

template < class T >
typename T::value_type f (const T& x) {
    return x.value;
}

template < class T >
T f (Dummy< T > const& x) {
    return x.value + 1;
}

int main (int, char**) {
    Dummy< int > d = { 1 };
    // No ambiguity here
    d.value = f(d);
    // This is ambiguous for *some* compilers
    int (* const f_ptr)(Dummy< int > const&) = f;
    return f_ptr( d );
}

clang++ 3.2、g++ 4.4 和 g++ 4.6 使用 -Wall -pedantic --std=c++98 编译它,没有警告。

g++ 4.7 和 g++ 4.8 然而给出以下错误信息:

test.cc: In function ‘int main(int, char**)’:
test.cc:15:45: error: converting overloaded function ‘f’ to type ‘int (* const)(const struct Dummy<int>&)’ is ambiguous
test.cc:6:18: error: candidates are: typename T::Type f(const T&) [with T = Dummy<int>; typename T::Type = int]
test.cc:9:3: error:                 T f(const Dummy<T>&) [with T = int]

这是较新版本的 g++ 的问题还是我的代码实际上是错误的?

如果是,人们将如何解决这种歧义?

最佳答案

Is this an issue with newer versions of g++ or is my code in fact wrong?

我想这是合法的代码(但我不太确定)。要添加到列表中:它确实使用 clang 3.3 和 icc 13.1.3 编译。

how would one go about resolving such an ambiguity?

你可以使用

    int (* const f_ptr)(Dummy< int > const&) = f<int>;

选择第二个重载或

    int (* const f_ptr)(Dummy< int > const&) = f<Dummy<int> >;

选择第一个。

如果您不想手动消除歧义(如我上面的建议),我可以建议使用 SFINAE 消除歧义的解决方法。我假设您可以使用 C++11(函数模板的默认模板参数),但我相信通过一些额外的工作它可以扩展到 C++98。

f 的定义更改为:

template < class T, class R = typename T::value_type>
R f (const T&) {
    return x.value;
}

template < class T, class R = T>
R f (Dummy< T > const&) {
    return x.value + 1;
}

有了这个,原始行(下面)在 gcc(4.7.3 和 4.8.1)中编译得很好:

int (* const f_ptr)(Dummy< int > const&) = f;

关于c++ - 转换重载函数不明确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19818391/

相关文章:

linux - 来自 gcc 的 pgo 的优化报告

c - iphone:如果 float 为负数,则转换为无符号整数的 float 将设置为 0?

c++ - “Undefined symbols for architecture x86_64”-再次(小例子)

c++ - 引用特定函数参数

统计分布类型的 C++ 模板用法

c++ - 如何在 VS2010 中痛饮?

c - 在内联 x86 程序集中是否未定义整数溢出?

C++ uniform_int_distribution 总是在第一次调用时返回 min()

java - 在java中将 "0.25000%"转换为double

java - 将某些数据类型设置到数据库中