从模板类中的Bool值超载成员
Overloading members from template class on bool value
我正在尝试避免在项目的主分支上概念,因此我需要使用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() {
编辑:删除复制/粘贴错误
1.应删除类名称的资格(即 Foo<Object, Shared>::
),以删除成员函数声明内部类定义。
2.默认模板参数不允许用于成员模板的课外定义,只需删除它们。
不允许默认参数
- 在会员模板的课外定义中(它们必须是 在班级主体内的声明中提供)
然后
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
}
live
作为替代方案,您可以使用标签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 {
// ...
}
}
因此,每个块仅在正确的版本中可用:
- 所以没有运行时分支(我希望无论如何在您的情况下都可以优化常规分支)
- 未选择的块可能只有在选择该分支的情况下才有有效的代码(当它取决于> type >)。
和C 20引入requires
:
template <typename Object, bool Shared = false>
class Foo {
public:
void bar() requires(Shared) {
// ...
}
void bar() requires(!Shared) {
// ...
}
};
这是您的代码修复后(最小,工作示例):
#include <type_traits>
#include <iostream>
template < typename Object, bool Shared = false >
class Foo {
public:
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() {
std::cout << "do something" << std::endl;
}
template < typename Object, bool Shared >
template < bool S, typename std::enable_if<!S>::type*>
void Foo<Object, Shared>::bar() {
std::cout << "do nothing" << std::endl;
}
int main() {
Foo<int> test;
test.bar<>();
test.bar<true>();
return 0;
}
这是一个额外的限定符和默认参数的问题
作为额外的注意,这是一个更干净的解决方案:
#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;
}
相关文章:
- 写入向量<向量<bool>>
- 让bool方法返回其他整数
- 寻找地理和伤害意味着超载
- 如何在 std::vector 中找到<bool>哪些索引是真的?
- Arduino-C++ bool 不会从 false 变为 true
- 没有可行的超载'='用于shared_ptr
- 为什么在这种情况下,bool 类型的输出等于 0?
- 显式 std::exception_ptr 转换为 bool 不存在.VS2010 错误?
- "专业化不参与超载"
- 错误:不能使用"显式"说明符声明 bool'
- 为什么 C++ 11 在 ios 类中添加了运算符 bool
- 从标准::字符串到标准::矢量<bool>的快速转换
- 为什么 bool 和 _Bool 如果它们在内存中占用 1 个字节,它们只能存储 0 或 1
- 通过 mpi 发送 c++ 标准::矢量<bool>
- 为什么使用Pool和Bool而不是int8_t或char
- 如何为地图< map<int,int> 、bool > 分配值?
- 为什么更改包含 psapi.h 的顺序会产生编译错误?(标识符 BOOL 未定义)
- C bool表达式作为函数参数调用错误的超载
- 在使用C 中使用多个三元运算符时,BOOL和ENUM类型超载的功能没有区分
- 从模板类中的Bool值超载成员