【发布时间】:2018-09-13 01:57:57
【问题描述】:
我正在研究自 C++17 以来可用的类模板推导。这是我想问的代码:
#include <iostream>
#include <cmath>
using std::endl;
using std::cout;
template<typename T>
struct MyAbs {
template<typename U>
MyAbs(U&& u) : t(std::forward<T>(u))
{ cout << "template" << endl;}
#ifdef ON
MyAbs(const T& t) : t(t) {}
#endif
T operator()() const
{
return std::abs(t);
}
T t;
};
/*
// may need the following
template<typename U>
MyAbs(U&&) -> MyAbs<typename std::remove_reference<U>::type>;
*/
int main()
{
const double d = 3.14;
cout << MyAbs(4.7)() << endl;
cout << MyAbs(d)() << endl;
return 0;
}
当MyAbs(const T&) 没有条件编译时(即没有-DON),clang++ 和g++ 都无法推导出模板参数T。给定-DON=1,两个编译器都构建了上面的简单示例。
首先,我也猜到应该扣不成功;编译器可以推断出U,但不能推断出T。我得到的编译错误是我所期望的。如果我弄错了,请告诉我。
如果我是正确的,那么,我无法理解为什么在添加MyAbs(const T&) 时使用U&& 的扣除成功。我期望用U&& 推断失败,而SFINAE 允许我在两种情况下调用MyAbs(const T&):4.7 和d。然而,发生的事情是不同的。这个程序似乎调用了 4.7 的模板版本和d 的非模板版本。
$ g++ -Wall -std=c++17 ~/a.cc -DON=1
$ ./a.out
template
4.7
3.14
模板版好像一下子变得可行了。这是预期的吗?如果有,是什么原因?
【问题讨论】:
标签: c++ templates c++17 template-argument-deduction