【问题标题】:Why C++ compiler chooses wrong function (templates)为什么 C++ 编译器选择错误的函数(模板)
【发布时间】:2019-02-23 13:52:54
【问题描述】:

我做了一些测试,遇到了这种奇怪的行为。

struct A{};

struct B : A{};

#include <iostream>

template<class T>
void fn2(T const &){
}

void fn2(A const &){
    std::cout << "Here\n";
}

template<class T>
void fn1(){
    T a;

    fn2(a);
}

int main(){
    fn1<B>();
}

我确实清理了代码。运行时,我希望它打印“here”。但是它调用fn2() 的模板版本。

我也在 Godbolt 中进行了测试。在那里我重写了函数fn1()fn2(),所以它们返回int。那时,编译器做了正确的事情。

这是我的编译方式:

$ gcc -Wall -Wextra -Wpedantic bug.cc  -lstdc++
$ ./a.out 
$ clang -Wall -Wextra -Wpedantic bug.cc  -lstdc++
$ ./a.out 
$ 

【问题讨论】:

  • 什么意思?程序从不打印“Here”,voidint 都不会。

标签: c++ templates gcc clang overload-resolution


【解决方案1】:

选择模板版本是因为它完全匹配(T 推断为B)。对于要调用的非模板版本,需要从BA的隐式版本;那么模板版本在重载决议中获胜。

T 被推断为A 或其派生类时,您可以将SFINAEstd::enable_ifstd::is_base_of 一起应用,以从重载集中消除模板版本。

template<class T>
std::enable_if_t<!std::is_base_of_v<A, T>> fn2(T const &){
}

【讨论】:

  • 您能详细说明一下吗,因为我可以更改一些更改,与您所说的无关,它会称为正确的版本。
  • @Nick 你的意思是你想要解决方法来调用非模板?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多