我可以用decltype替换enable_if吗?

时间:2017-01-17 13:59:02

标签: c++ visual-studio gcc decltype enable-if

understanding decltype with 2 arguments我想知道之后,我可以使用它代替enable_if吗?例如:

template <typename T>
decltype(T(), declval<bool>()) isConstructable() { return true; }

在Visual Studio 2015上成功isConstructable<int>并在isConstructable<istream>失败:http://rextester.com/YQI94257但在gcc I have to do上:

template <typename T>
enable_if_t<decltype(T(), true_type())::value, bool> isConstructable() { return true; }

decltype版本是否有效,或者我只是在利用非标准的Microsoftianisim?

2 个答案:

答案 0 :(得分:1)

std::declval<bool>()的类型为bool&&,而不是bool。发出警告的地方 - true需要通过引用返回。

这样的事情应该在没有警告的情况下进行编译:

bool ok() { return true; }

template <typename T>
decltype(T(), ok()) is_constructable() { return true; }

int main() {
    cout << is_constructable<int>() << endl;
}

答案 1 :(得分:0)

正如RustyX's answer提到的那样:

is_rvalue_reference_v<decltype(isConstructable<int>())>

On gcc you'll get trueon Visual Studio you'll get false。因此,gcc失败的原因是它总是未定义的行为将r值引用返回到即将被销毁的对象:https://stackoverflow.com/a/29332571/2642059

declval应该返回r值引用吗?

declval&#39}的返回类型实际上是:

  

T&&除非T(可能是cv限定的)void,在这种情况下返回类型为T

因此,这是一个&#34; Microsoftianisim&#34;。可以通过删除declval

来完成与平台无关的代码
template <typename T>
decltype(T(), bool()) isConstructable() { return true; }

gcc Example Visual Studio Example

Jarod42 has pointed out T可能会使,运算符超载,在这种情况下需要缓冲void()

template <typename T>
decltype(T(), void(), bool()) isConstructable() { return true; }