VS2013 上的 SFINAE 错误
SFINAE error on VS2013?
我一直在尝试任何我能想到的事情来使_CallWithRightmostArgsInner
函数正确失败,以便SFINAE可以正常工作,通过这次尝试,VS2013给了我错误: error C2039: 'type' : is not a member of 'std::enable_if<false,void>'
有什么想法吗? 有没有更好的替代方案? 这里的想法是,我想对函数进行函数调用,前提是函数采用 NumArgs 表示的数字或参数。 最后两个可变参数应转发给函数并返回结果。
template <typename Function, int NumArgs>
class SplitParameters {
public:
typedef typename function_traits<Function>::result_type result_type;
template <typename ... RightArgs>
static result_type CallWithRightmostArgs(const Function& call, RightArgs && ... rightArgs) {
static_assert(sizeof...(RightArgs) >= NumArgs, "Unable to make function call with fewer than minimum arguments.");
return _CallWithRightmostArgs(call, std::forward<RightArgs>(rightArgs)...);
}
private:
template <typename ... RightArgs>
static result_type _CallWithRightmostArgs(const Function& call, RightArgs && ... rightArgs) {
return _CallWithRightmostArgsInner(call, std::forward<RightArgs>(rightArgs)...);
}
// note the '==' vs '!=' in these two functions. I would assume that only one could exist
template <typename LeftArg, typename ... RightArgs, typename std::enable_if<sizeof...(RightArgs) != NumArgs>::type* = 0>
static result_type _CallWithRightmostArgsInner(const Function& call, LeftArg, RightArgs && ... rightArgs) {
return _CallWithRightmostArgs(call, std::forward<RightArgs>(rightArgs)...);
}
template <typename LeftArg, typename ... RightArgs, typename std::enable_if<sizeof...(RightArgs) == NumArgs>::type* = 0>
static result_type _CallWithRightmostArgsInner(const Function& call, LeftArg, RightArgs && ... rightArgs) {
return call(std::forward<RightArgs>(rightArgs)...);
}
};
通过将代码更改为 g++-4.8,我得到了它
#include <iostream>
template <class T>
struct function_traits
{
typedef void result_type;
};
template <typename Function, int NumArgs>
class SplitParameters {
public:
typedef typename function_traits<Function>::result_type result_type;
template <typename ... RightArgs>
static result_type CallWithRightmostArgs(const Function& call, RightArgs && ... rightArgs) {
static_assert(sizeof...(RightArgs) >= NumArgs,
"Unable to make function call with fewer than minimum arguments.");
return _CallWithRightmostArgs(call, std::forward<RightArgs>(rightArgs)...);
}
private:
template <typename ... RightArgs>
static result_type _CallWithRightmostArgs(const Function& call, RightArgs && ... rightArgs) {
return _CallWithRightmostArgsInner(call, std::forward<RightArgs>(rightArgs)...);
}
// note the '==' vs '!=' in these two functions. I would assume that only one could exist
template <typename LeftArg, typename ... RightArgs, class = typename std::enable_if<sizeof...(RightArgs) != NumArgs -1 >::type>
static result_type _CallWithRightmostArgsInner(const Function& call, LeftArg, RightArgs && ... rightArgs) {
return _CallWithRightmostArgsInner(call, std::forward<RightArgs>(rightArgs)...);
}
template <typename ... RightArgs, class = typename std::enable_if<sizeof...(RightArgs) == NumArgs>::type>
static result_type _CallWithRightmostArgsInner(const Function& call, RightArgs && ... rightArgs) {
return call(std::forward<RightArgs>(rightArgs)...);
}
};
void f(int i, int j)
{
std::cout << i << ' ' << j << std::endl;
}
int main()
{
SplitParameters<decltype(f), 2>::CallWithRightmostArgs(f, 1, 2, 3, 4);
}
编译器不喜欢你从_CallWithRightmostArgsInner
调用_CallWithRightmostArgs
,我假设你实际上是在尝试调用Inner
函数。
g++ 也不喜欢在模板参数列表中将0
转换为void*
,所以我将其更改为 class = enable_if<...>::type
。
我没有详细调查它失败的原因,希望这对你来说已经足够好了。
编辑:关于被拒绝typename enable_if<...>::type* = 0
,我记得std::array
也有类似的问题:
template <class T, int size>
void f(const std::array<T,size>&){}
这个小片段本身编译得很好,但是当你这样做时:
std::array<int,4> a;
f(a);
g++ gives:
test3.cpp: In function ‘int main()’:
test3.cpp:9:8: error: no matching function for call to ‘f(std::array<int, 4ul>&)’
f(a);
^
test3.cpp:9:8: note: candidate is:
test3.cpp:4:6: note: template<class T, int size> void f(const std::array<T, size>&)
void f(const std::array<T,size>&){}
^
test3.cpp:4:6: note: template argument deduction/substitution failed:
test3.cpp:9:8: note: mismatched types ‘int’ and ‘#‘integer_cst’ not supported by dump_type#<type error>’
f(a);
^
test3.cpp:9:8: note: ‘std::array<int, 4ul>’ is not derived from ‘const std::array<T, size>’
事实证明,问题是我将模板声明为size
参数的int
,但编译器得到的是一个与int
不同的std::size_t
,即使您可以轻松地在它们之间进行转换。
在上面的例子中,我什至不能用= NULL
替换= 0
,因为这只是一个0L
文字,我必须做= (void*)0
才能让编译器接受它(因为默认的enable_if<true>::type
类型是void
)。
- VS2017 上 SFINAE 的编译错误
- 进行 SFINAE 练习时编译错误
- 尝试编译SFINAE检查中使用的方法体时发生编译错误
- C++ 带有 decltype 的 SFINAE:替换失败成为错误?
- 使用模板时可能是编译器中的 SFINAE 错误?
- 尝试使用具有尾随返回类型的 lambda 进行 SFINAE 时出现硬错误
- 如何对 SFINAE 进行"deep",即当替换导致代码中进一步出现一些编译错误时?
- 尾随返回类型中带有 SFINAE 的 GCC 错误
- 防止编码器错误 - 忘记在"std::enable_if<>::type"中添加"::type" (SFINAE)
- 为什么这个 SFINAE 在 gcc 中给出错误
- 在模板 SFINAE 约束中使用间接寻址级别会导致硬错误
- 使用C ,使用SFINAE测试静态成员的存在,返回错误的值
- 将 SFINAE 上下文中不正确的模板实例化的硬错误转变为软错误
- 在VS2015编译中键入Sfinae,但会产生错误
- VC++ SFINAE 给出错误 C2070:"重载函数":操作数大小非法
- 从MSVC2015更新2移植到GCC 5.3-SFINAE错误
- C++模板sfinae错误
- 模板实例化上的SFINAE错误
- 使用 SFINAE 但不创建编译错误
- 替换失败不是static_cast的错误(SFINAE)问题