在以下代码中,我想考虑将Op
返回的函数(void
s)视为返回true
。类型Retval
和Op
的返回值始终匹配。我无法使用此处显示的类型特征进行区分,并且由于存在其他模板变量Retval
和{{1},尝试基于Op
创建部分模板特化失败}。
如何在模板专业化中仅对某些变量进行专门化而不会出现错误?是否有其他方法可以根据Args
的返回类型更改行为?
Op
答案 0 :(得分:1)
您需要明确的专业化,而不是部分专业化。
template <typename Retval, typename Op, typename... Args>
Retval single_op_wrapper(
Retval const failval,
char const *const opname,
Op const op,
Cpfs &cpfs,
Args... args) {
try {
CallContext callctx(cpfs, opname);
Retval retval;
if (std::is_same<bool, Retval>::value) {
(callctx.*op)(args...);
retval = true;
} else {
retval = (callctx.*op)(args...);
}
assert(retval != failval);
callctx.commit(cpfs);
return retval;
} catch (CpfsError const &exc) {
cpfs_errno_set(exc.fserrno);
LOGF(Info, "Failed with %s", cpfs_errno_str(exc.fserrno));
}
return failval;
}
template<typename Op, typename... Args> void single_op_wrapper<void, Op, Args>(...) {
...
}
编辑:忘了你在写一个函数,而不是一个类。
答案 1 :(得分:0)
模板功能不能部分专业化。您可以执行以下操作:您可以使用单个静态方法将函数包装到类模板中并专门化类模板,或者您可以使用SFINAE在不同的模板函数中选择最佳函数选择:
template <typename O, typename Args...>
void single_op_wrapper( /* all but failval */ ) { // [+]
// implementation for void
}
template <typename R, typename O, typename Args...>
typename boost::enable_if< boost::is_same<R,bool>, bool >::type // bool if condition is met
single_op_wrapper( /* all args */ ) {
// implementation for R being a bool
}
template <typename R, typename O, typename Args...>
typename boost::enable_if< boost::is_same<R,char> >::type // by default bool
single_op_wrapper( /* all args */ ) {
// implementation for void return
}
template <typename R, typename O, typename Args...>
typename boost::disable_if_c< boost::is_same<R,char>::value //[*]
|| boost::is_same<R,bool>::value
, R >::type
single_op_wrapper( /* all args */ ) {
// implementation when R is neither bool nor void
}
在void [+]的单独模板上:
在C ++中,你不能拥有一个带有void
类型参数的函数。这意味着您不能使用与void
案例相同的参数,因为您正在使用其他参数。
在元编程方面:
这里有一些棘手的问题...... enable_if
是一个元函数,如果条件满足则定义内部类型,否则不定义。当编译器尝试替换模板中的类型时,如果满足条件,则返回类型将仅有效(并且因此该函数是候选函数)。 disable_if
元函数具有相反的行为。直接变量enable_if
/ disable_if
将元函数作为第一个参数,并选择将类型作为第二个参数。第二个版本enable_if_c
/ disable_if_c
将布尔值作为第一个参数。
在[*]中注意功能必须是独占的。也就是说,如果对于给定类型,不止一个模板是候选模板,因为它们都不是其他模板的特化,编译器将以模糊错误停止。这就是在最后一个模板中使用disable_if
的原因。
注意:我使用了boost
命名空间而不是std
,因为我没有在c ++ 0x中使用元编程,但我相信您可以使用boost
命名空间更改std
命名空间编译器中的{{1}}。提前检查文档!
答案 2 :(得分:0)
这是我用来绕过 C++ 中函数缺少部分模板特化的技巧。基本上,这依赖于函数重载和多个函数声明之间的灰色区域,由于 SFINAE 规则,这些函数声明不会导致编译器错误(所有 enable_if_t
布尔条件都是互斥的,因此给定任何特定编译单元,只有一个声明是有效的上下文)
template < class T, std::enable_if_t< sizeof(T) == 4, int > = 0 >
T do_transform(T inp) {
// 4 byte implementation
}
template < class T, std::enable_if_t< sizeof(T) == 8, int > = 0 >
T do_transform(T inp) {
// 8 byte implementation
}
template <class T, std::enable_if_t< sizeof(T) > 8, int> = 0 >
T do_transform(T inp) {
// very much wide word types
}