c++ - 推导参数失败,适用于返回值

标签 c++ templates c++11 sfinae

我尝试在函数参数上使用 std::enable_if 来触发 SFINAE。编译失败并出现此错误:

type_nonsense.cpp:20:5: error: no matching function for call to 'c'
    c(SOME::VALUE);
    ^
type_nonsense.cpp:13:6: note: candidate template ignored: couldn't infer
      template argument 'T'
void c(typename std::enable_if<std::is_enum<T>::value, T>::type t) {}
     ^
1 error generated.

std::enable_if 移动到返回类型或虚拟模板参数都可以正常工作。为什么?


#include <type_traits>

// Works
template <typename T, typename dummy = typename std::enable_if<std::is_enum<T>::value, T>::type>
void a(T t) {}

// Works
template <typename T>
typename std::enable_if<std::is_enum<T>::value, void>::type b(T t) {}

// Fails to compile
template <typename T>
void c(typename std::enable_if<std::is_enum<T>::value, T>::type t) {}

enum class SOME { VALUE };

int main() {
    a(SOME::VALUE);
    b(SOME::VALUE);
    c(SOME::VALUE);
}

最佳答案

嵌套名称说明符中的依赖类型是模板参数推导的非推导上下文,因此不能用于确定 T 的类型。将 std::enable_if 放在返回类型中或作为默认模板参数是可行的,因为在这些上下文中不会推导 T 的类型。

如果你需要把它作为一个参数,你可以这样做:

template <typename T>
void c(T t, typename std::enable_if<std::is_enum<T>::value>::type* = nullptr) {}

这是有效的,因为T 是由第一个 参数推导出来的,而不是第二个。

关于c++ - 推导参数失败,适用于返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26638902/

相关文章:

c++ - joySetCapture 不适用于 fChanged = false

模板声明中省略了 C++ 类型参数。但是,在成员函数的定义中又如何呢?

c++ - C++1 1's std::string' 的底层表示是否保证有终止空字符?

c++ - Variadic 模板模板和 SFINAE

C++ 从内存中读取 1 位?

c++ - 使用 boost::asio(visual studio12, x64) Unresolved external 问题

c++ - 为什么对重载函数的调用不明确?

c++ - 概括这些代码行?

c++ - 适用于存储和计算最高得分 K 项的数据结构

c++ - 在一个普通的可复制结构中, move 语义应该被实现吗?