测试用例
在内部数据类型的情况下,让函数的返回类型与从标头auto foo(T f)调用时相同:sin(f)cmathf
template <typename T>
auto foo(T f) -> decltype(sin(f))
{
using std::sin;
return sin(f);
}
这已破了。不查找 inside sin(f),因此只找到返回类型为的变体。下面的程序演示了:decltypestdCsin(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 可能无济于事。