Reputation: 493
I have two class A and B, with a common function doing some operation on both of them with just a minor difference.
I tried using std::is_same
, but looks like it won't prevent compile-time issues.
class A {
public:
void aSpecificFunctionToA() {
}
};
class B {
};
template<typename T>
void someFunction(T obj) {
if(std::is_same<T, A>::value)
{
obj.aSpecificFunctionToA();
}
}
How to tackle this situation?
Upvotes: 1
Views: 147
Reputation: 37657
I prefer simple old fashion solution:
#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();
}
Upvotes: 0
Reputation: 2870
If you have more than one class having aSpecificFunctionToA
(well, in this case the name is poorly choose) you can use SFINAE.
Full 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{});
}
Upvotes: 0
Reputation: 493
This code prevented the compiler to build that particular if block based on a const bool expression.
const bool flag = std::is_same<T, A>::value;
#if(flag)
{
obj.aSpecificFunctionToA();
}
#endif
Upvotes: -1
Reputation: 60218
If you can use c++17, then you can use if constexpr
to conditionally compile code if it satisfies some constraints.
template<typename T>
void someFunction(T obj) {
if constexpr (std::is_same<T, A>::value)
{
obj.aSpecificFunctionToA();
}
// ... code for all Ts
}
Before c++17, you can use an overload for A
, and put the code that is common to all T
s into a separate function:
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);
}
Upvotes: 3