如何解决如何检查一个类是否具有特定功能以避免编译时问题?
我有两个类A和B,它们的通用功能对它们两个都做了一些操作,只是有微小的区别。
我尝试使用std::is_same
,但看起来并不能防止编译时问题。
class A {
public:
void aSpecificFunctionToA() {
}
};
class B {
};
template<typename T>
void someFunction(T obj) {
if(std::is_same<T,A>::value)
{
obj.aSpecificFunctionToA();
}
}
如何处理这种情况?
解决方法
如果可以使用c ++ 17,则可以使用if constexpr
在满足某些约束的情况下有条件地编译代码。
template<typename T>
void someFunction(T obj) {
if constexpr (std::is_same<T,A>::value)
{
obj.aSpecificFunctionToA();
}
// ... code for all Ts
}
在c ++ 17之前,您可以对A
使用重载,并将所有T
的通用代码放入单独的函数中:
template<typename T>
void common_code(T obj) {
// ... code for all Ts
}
template<typename T>
void someFunction(T obj) {
common_code(obj);
}
void someFunction(A obj) {
obj.aSpecificFunctionToA();
common_code(obj);
}
,
如果您有多个拥有aSpecificFunctionToA
的班级(那么,在这种情况下,名称选择不多),则可以使用SFINAE。
完整的C ++ 11:
#include <vector>
#include <functional>
#include <iostream>
#include <memory>
#include <type_traits>
namespace detail_traits
{
template <class...>
struct Args
{
};
template <class... T>
using void_t = void;
template <class T,class args,class = void>
struct has_aSpecificFunctionToA : std::false_type
{
};
template <class T,class... args>
struct has_aSpecificFunctionToA<
T,Args<args...>,void_t<decltype(std::declval<T>().aSpecificFunctionToA(std::declval<args>()...))>> : std::true_type
{
};
} // namespace detail_traits
template <class T,class... Args>
using has_aSpecificFunctionToA = typename detail_traits::has_aSpecificFunctionToA<T,detail_traits::Args<Args...>>;
class A
{
public:
void aSpecificFunctionToA() {
std::cout << "aSpecificFunctionToA" << std::endl;
}
};
class B
{
};
template <typename T>
typename std::enable_if<has_aSpecificFunctionToA<T>::value>::type someFunction(T obj)
{
obj.aSpecificFunctionToA();
}
template <typename T>
typename std::enable_if<!has_aSpecificFunctionToA<T>::value>::type someFunction(T )
{
std::cout << "some code for class without aSpecificFunctionToA" << std::endl;
}
int main()
{
std::cout << has_aSpecificFunctionToA<A>::value << std::endl;
std::cout << has_aSpecificFunctionToA<B>::value << std::endl;
someFunction(A{});
someFunction(B{});
}
,
我更喜欢简单的老式解决方案:
#define LOG std::cout << __PRETTY_FUNCTION__ << '\n'
class A {
public:
void aSpecificFunctionToA() {
LOG;
}
};
class B {
};
template<typename T>
void someFunction(T obj) {
LOG;
}
void someFunction(A obj) {
LOG;
obj.aSpecificFunctionToA();
}
,
此代码阻止编译器基于const bool表达式构建特定的if块。
const bool flag = std::is_same<T,A>::value;
#if(flag)
{
obj.aSpecificFunctionToA();
}
#endif
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。