测试用例
在内部数据类型的情况下,让函数的返回类型与从标头auto foo(T f)
调用时相同:sin(f)
cmath
f
template <typename T>
auto foo(T f) -> decltype(sin(f))
{
using std::sin;
return sin(f);
}
这已破了。不查找 inside sin(f)
,因此只找到返回类型为的变体。下面的程序演示了:decltype
std
C
sin(double)
double
#include <cmath>
#include <iostream>
#include <typeinfo>
namespace meh {
struct Nanometer {};
struct SinfulNanometer {};
SinfulNanometer sin(Nanometer) { return SinfulNanometer(); }
}
template <typename T>
auto foo(T f) -> decltype(sin(f))
{
using std::sin;
std::cout << typeid(decltype(sin(f))).name() << '\n';
}
int main () {
std::cout << typeid(decltype(foo(0.))).name() << '\n'
<< typeid(decltype(foo(0.f))).name() << '\n'
<< typeid(decltype(foo(meh::Nanometer()))).name() << '\n';
foo(0.);
foo(0.f);
foo(meh::Nanometer());
}
输出:
d
d
N3meh15SinfulNanometerE
d
f
N3meh15SinfulNanometerE
输出表明返回类型始终double
为foo->float
and foo->double
,仅在 内 ,因为导入所有重载的 ,才找到foo()
正确的类型。sin(float|double)
using std::sin
我想知道在 gremium 中是否已经考虑过这种情况,但这不是我的问题。
问题
我的问题是:
什么是让foo
具有相同返回类型的函数与名称在namespace std
或 ADL-looked-up 的函数相同的明智方法?
非工作解决方法:
template <typename T>
auto foo(T f) -> decltype(std::sin(f)); // Will miss sin(Nanometer)
标准提案?
template <typename T>
auto foo(T f) -> decltype(using std::sin; sin(f));
使用排列enable_if
的方式是代码是自记录的。enable_if
是元编程的一个很好的练习。但是要快速掌握一个看似简单的功能,恕我直言,这不是正确的事情,因此不符合可维护性的精神。
编辑:我也decltype
习惯于不那么隐晦地使用 SFINAE,因此带有新auto foo() {....}
声明的 C++14 可能无济于事。