template<bool, class T, class U>
struct IF_ELSE { using type = T; };
template<class T, class U>
struct IF_ELSE<false, T, Y> { using type = U; }
template<class T>
class Object {
Object baz(IF_ELSE<boolean_condition<T>::value, foo_class, bar_class>::type param) {
return Object(param);
}
};
您好我正在尝试创建一个方法,该方法返回一个基于某些模板条件初始化的对象。上面的代码工作正常,但我想使用默认构造函数(无参数)
template<class T>
class Object {
Object baz(IF_ELSE<boolean_condition<T>::value, foo_class, void>::type param) {
return Object(param);
}
};
但是不能将void用作类型(尽管void foo(void);
是有效的decleration)
有没有这样做?
注记。我不想使用模板专业化。虽然这是针对这个特定问题的解决方案,但在我当前的项目中使用专业化会很不方便。我个人更喜欢使用IF_ELSE而不是专业化,因为我发现它更容易理解。
我能想到的唯一解决方法就是......
template<class T>
class Object {
Object baz(IF_ELSE<boolean_condition<T>::value, foo_class, int>::type param = 0) {
if (param == 0)
return Object();
else
return Object(param);
}
};
如果有人拥有更复杂的解决方案,那就太棒了。非常感谢。
---------------------------------- EDITED ------------ ------------------
这种解决方法更好一些(受Oisyn的启发)它或多或少地结合了参数专业化和默认参数这两个方面的优点。可能会有点快,因为它躲过if语句。
template<class T>
class Object
{
public:
struct MAKE_ILLEGAL {};
template<class param>
Object(param p) {/*do stuff */}
Object() {/* default */ }
template<bool b>
Object<T> baz(std::conditional_t<b, int, MAKE_ILLEGAL> param)
{ return Object<T>(param); }
template<bool b>
Object<T> baz(std::conditional_t<b, MAKE_ILLEGAL, int> value = 0)
{ return Object<T>(); }
};
int main() {
Object<double> obj;
obj.baz<false>();
}
答案 0 :(得分:2)
编辑显然,您不允许在类型相关的上下文中使用解析为void
的内容作为函数参数。我使用不同的解决方案相应地编辑了我的答案。原始答案可以在下面阅读。
// A helper that always yields true so we can make the condition type-dependent
// on arbitrary template parameters
template<class T>
constexpr bool true_v = true;
template<class T>
class Object
{
public:
template<class U = void, std::enable_if_t<Condition<T>::value && true_v<U>, int> = 0>
Object baz(foo_class param)
{ return Object(param); }
template<class U = void, std::enable_if_t<!Condition<T>::value && true_v<U>, int> = 0>
Object baz()
{ return Object(); }
};
只要我们不处理复制/移动ctors和复制/移动赋值运算符(可能没有模板化)等特殊方法,我们就可以始终应用常规的SFINAE技巧。我们只需要使用默认模板参数对baz
进行模板化,并确保std::enable_if
使用的条件依赖于该方法的模板参数(而不仅仅是T
{ {1}})
原始回答
Object<T>
这个想法是你创建了两个重载,一个用于单个参数,一个用于无。通过有选择地用不可访问的虚拟类型替换参数,您可以确保在不合适时永远无法调用该过载。