编辑:问题解决了,这只是错误的函数声明顺序。
当我试图解决一眼看上去非常微不足道的问题时,我偶然发现了无法解释的行为。
我想以递归方式处理任意int数组,当然我必须以某种方式停止递归。 由于模板函数(如
)无法对具体数字进行部分特化#include <algorithm>
#include <iostream>
using namespace std;
// -------------------------------------------------------------
template<typename T, int N>
void foo(T const& param, typename enable_if<N != 0, int>::type* = 0)
{
cout << "recursive step " << N << endl;
/* --- This was, what I desired: --- */
//foo<T, N - 1>(param);
/* --- THIS IS CAUSING AN ERROR! --- */
foo<T, 0>(param);
}
// -------------------------------------------------------------
template<typename T, int N>
void foo(T const& param, typename enable_if<N == 0, int>::type* = 0)
{
cout << "finish recursion" << endl;
}
// =============================================================
int main()
{
int a[5] = {0, 1, 2, 3, 4};
foo<decltype(a), 5>(a);
/* --- SAME CALL AS WITHIN foo(), BUT CAUSING NO ERROR! --- */
foo<decltype(a), 0>(a);
}
),我试图用SFINAE假装这个。但是当我想从第一个调用第二个SFNIAE函数时,我得到一个编译器错误。 完整的代码示例:
{{1}}
编译器告诉我: main.cpp:9:Fehler:'struct std :: enable_if'中没有名为'type'的类型 所以看来他以某种方式无法解决第二个功能。 但是,如果我从main()调用该函数,则不是问题。
这是我第一次参加SFINAE,我希望我没有犯过任何琐碎的错误。 感谢所有读过这篇文章的人!
答案 0 :(得分:1)
我对此Clang's helpfulness感到惊喜:
main.cpp:14:5: error: call to function 'foo' that is neither visible in the template definition nor found by argument-dependent lookup foo(param); ^ main.cpp:29:5: note: in instantiation of function template specialization 'foo' requested here foo(a); ^ main.cpp:19:6: note: 'foo' should be declared prior to the call site void foo(T const&, typename std::enable_if::type* = 0) ^
我的意思是,它距离登录Stack Overflow只有一步之遥并给出答案。反正。
将第二个函数的声明添加到第一个函数之上,以便您可以从其中调用它:
template<typename T, int N>
void foo(T const&, typename std::enable_if<N == 0, int>::type* = 0);
请注意,您还必须从定义中删除默认参数。
答案 1 :(得分:1)
你需要切换定义的顺序(或者在正常情况之前声明普通的情况),正常情况下看不到简单的情况,所以它不能调用它:
template<typename T, int N>
void foo(T const& param, typename enable_if<N == 0, int>::type* = 0) {
cout << "finish recursion" << endl;
}
template<typename T, int N>
void foo(T const& param, typename enable_if<N != 0, int>::type* = 0) {
cout << "recursive step " << N << endl;
foo<T, N - 1>(param);
}
请注意,您可以在此处使用辅助类来避免此enable_if
(并且还更改签名以便您可以让编译器推导出参数):
template<typename T, int N>
struct foo_h {
static void call(T const& param) {
foo_h<T, N - 1>::call(param);
}
};
template<typename T>
struct foo_h<T, 0> {
static void call(T const& param) {
}
};
template<typename T, int N>
void foo(const T (¶m)[N]) {
foo_h<const T[N], N>::call(param);
}
然后:
int arr[] = {1, 2, 3, 4, 5};
foo(arr); // Automatic template parameters deduction!