【发布时间】:2018-01-01 19:41:40
【问题描述】:
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); 是一个有效的声明)
有没有办法做到这一点?
注释。我不想使用模板专业化。尽管这是针对此特定问题的解决方案,但仅在我当前的项目中使用专业化会很不方便。我个人更喜欢使用 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);
}
};
如果有人有更复杂的解决方案,那就太好了。非常感谢。
----------------------已编辑------------ ------------------
这个解决方法更好一些(受 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>();
}
【问题讨论】:
-
我认为没有比您的解决方法更好的选择(忽略专业化)。此外,您的
IF_ELSE可以替换为std::conditional[_t]。 -
您可以将
Object设为非模板化,而改为使用template <typename ...T> Object baz(T &&... params),但我不确定它是否适用于您的设计。 -
你能做到
auto f = []()->void {};,然后在模板参数中传递void而不是decltype(someFunc()) -
然后你可以创建一个别名:
template <bool A, typename B, typename C> using IF_ELSE = std::conditional_t<A,B,C>;。那么你就不需要一直写::type了。 -
@JosephFranciscus,
conditional这个名字已经在 C++ 模板元程序员中建立起来。使用不同的名称需要任何人阅读代码来了解这是什么,然后意识到它只是std::conditional。
标签: c++ templates template-meta-programming