我试图避开项目主分支上的概念,所以我需要type_trait
的某种替代方案:
我需要一个类,其中一些函数会根据bool
值而改变。
有人已经建议我分开我的课,但这个案例在这里没有意义。对于某些上下文,如果可以共享池的对象类型,则删除函数和其他一些池将会更改。
所以我尝试使用std::enable_if
,但仍然存在一些错误(我希望声明和实现分开)。
#include <type_traits>
template < typename Object, bool Shared = false >
class Foo {
template < bool S = Shared, typename std::enable_if<S>::type* = nullptr >
void bar();
template < bool S = Shared, typename std::enable_if<!S>::type* = nullptr >
void bar();
};
template < typename Object,
bool Shared >
template < bool S, typename std::enable_if<S>::type* = nullptr >
void Foo<Object, Shared>::bar() {
//do something
}
template < typename Object,
bool Shared >
template < bool S, typename std::enable_if<!S>::type* = nullptr >
void Foo<Object, Shared>::bar() {
//do nothing
}
int main() {
Foo<int> test;
return 0;
}
Test3.cpp:16:33: error: default argument for template parameter for class enclosing ‘void Foo<Object, Shared>::bar()’
void Foo<Object, Shared>::bar() {
^
Test3.cpp:24:33: error: default argument for template parameter for class enclosing ‘void Foo<Object, Shared>::bar()’
void Foo<Object, Shared>::bar() {
编辑:删除了复制/粘贴错误
答案 0 :(得分:4)
1.对于成员函数声明在类定义中,应删除类名(即Foo<Object, Shared>::
)的限定。
2. Default template arguments不允许用于成员模板的类外定义,只需将其删除即可。
不允许使用默认参数
- 在成员模板的类外定义中(必须是 在类体内的声明中提供)
然后
template < typename Object, bool Shared = false >
class Foo {
template < bool S = Shared, typename std::enable_if<S>::type* = nullptr >
void bar();
template < bool S = Shared, typename std::enable_if<!S>::type* = nullptr >
void bar();
};
template < typename Object,
bool Shared >
template < bool S, typename std::enable_if<S>::type* >
void Foo<Object, Shared>::bar() {
//do something
}
template < typename Object,
bool Shared >
template < bool S, typename std::enable_if<!S>::type* >
void Foo<Object, Shared>::bar() {
//do nothing
}
答案 1 :(得分:1)
以下是您的代码一旦修复(最小,工作示例):
$(document).on('click', '#buttonSelector', function () {
$(this).addClass('disabled');
});
这是一个额外限定符和默认参数的问题,不能在类定义之外重复。
答案 2 :(得分:1)
另外请注意,这是一个更清洁的解决方案:
#include <type_traits>
#include <iostream>
template<bool b>
using allow_if = typename std::enable_if<b>::type;
template <typename Object, bool Shared = false>
class Foo {
public:
template<bool S = Shared>
allow_if<S> bar();
template<bool S = Shared>
allow_if<!S> bar();
};
template<typename Object, bool Shared>
template<bool S>
allow_if<S> Foo<Object, Shared>::bar() {
std::cout << "do something" << std::endl;
}
template<typename Object, bool Shared>
template<bool S>
allow_if<!S> Foo<Object, Shared>::bar() {
std::cout << "do nothing" << std::endl;
}
int main() {
Foo<int> test;
test.bar<>();
test.bar<true>();
return 0;
}
答案 3 :(得分:1)
作为替代方案,您可以使用tag-dispatching:
template <typename Object, bool Shared = false>
class Foo {
public:
void bar() { bar(std::integral_constant<bool, Shared>{}); }
private:
void bar(std::true_type);
void bar(std::false_type);
};
template <typename Object, bool Shared>
void Foo<Object, Shared>::bar(std::true_type) { /**/ }
template <typename Object, bool Shared>
void Foo<Object, Shared>::bar(std::false_type) { /**/ }
从C ++ 17开始,您可以使用if constexpr
:
template <typename Object, bool Shared = false>
class Foo {
public:
void bar() {
if constexpr (Shared) {
// ...
} else {
// ...
}
}
所以每个块只能以正确的版本提供: