Checking if a function with a given signature exists in c++ - c++

So I was looking for ways to check whether a function with a particular argument exists. I have a templated method which relies on an external function (external from the class) to do the job:
template <class Moo>
void exportDataTo(Moo& ret){
extended_solid_loader(ret, *this);
}
At multiple points in the project I have macros which define extended_solid_loader for different types, but now I want to be able to use a default function if extended_solid_loader hasn't been defined for that particular class type.
I came across this:
Is it possible to write a template to check for a function's existence?
but it seems a little different, in that I'm not checking for a method, but rather a definition of a function with a particular argument type.
Is this possible right now?

You can just provide a function template for extended_solid_loader providing a default implementation, and users who want to use something other than the default implementation just specialize that.
template<class T>
void extended_solid_loader(T & ret, SomeClass & obj) {
// default implementation here
}
template<>
void extended_solid_loader<MooClass>(MooClass & ret, SomeClass & obj) {
// special implementation for MooClass here
}

You don't actually have to do anything particularly special. Just make sure there's a version of that function available to the template and let ADL do the dirty work. Check out this example:
#include <iostream>
namespace bob {
struct X {};
void f(X const&) { std::cout << "bob::f\n"; }
}
namespace ed {
template < typename T >
void f(T const&) { std::cout << "ed::f\n"; }
template < typename T >
struct test
{
void doit() // not called f and no other member so named.
{ f(T()); }
};
}
int main()
{
ed::test<int> test1;
ed::test<bob::X> test2;
test1.doit();
test2.doit();
std::cin.get();
}
Works without the namespace stuff too (non-templates have preference). I just used that to show that ADL will pick it up when you do.
Your original question was interesting. Found a way to do it in C++0x:
template < typename T >
struct fun_exists
{
typedef char (&yes) [1];
typedef char (&no) [2];
template < typename U >
static yes check(decltype(f(U()))*);
template < typename U >
static no check(...);
enum { value = sizeof(check<T>(0)) == sizeof(yes) };
};
void f(double const&) {}
struct test {};
#include <iostream>
int main()
{
std::cout << fun_exists<double>::value << std::endl;
std::cout << fun_exists<test>::value << std::endl;
std::cin.get();
}

Related

How to write the same function with same name that handles different class arguments almost similarly in C++?

I have two different classes
class A_class {
public:
string member_to_add_to;
}
and
class B_class {
string member_to_add_to;
}
They both are almost similar with a slight difference in member variables. There is no inheritance involved. They both are used in different sections that do not merge together. I know it is not a good design but we don't have time to fix it now as the code base is large.
Then there is the Modifier class that takes a reference to an object of either A_class or B_class and makes some modifications to the class objects.
class Modifier() {
method1(A_class& object_ or B_class& object);
method2(A_class& object_ or B_class& object);
}
I need to write a function called doSomething() inside the Modifier class that takes in an object that is either A_class or B_class along with a string parameter that sets a member variable member_to_add_to to the string parameter and calls other methods within Modifier. Exactly only two lines differ based on they type of object being fed into this function.
void doSomething(A_class (or) B_class object_to_modify, string member_value) {
object_to_modify.member_to_add_to = member_value;
// after this 5 to 10 steps that call other methods taking a reference to object_to_modify but do the same thing
method1(object_to_modify);
method2(object_to_modify);
//etc.,
}
Apart from the fact that it involves these two classes, everything else inside this function is the same exact code.
Should I just use function overloading for both the objects separately and replicate the code inside it twice in 2 functions except for the lines that differ?
Is there a more optimized/readable way of doing this?
Use a template function:
#include <iostream>
#include <type_traits>
struct A {
char const* data;
};
struct B {
char const* data;
};
template <typename T,
std::enable_if_t<std::is_same_v<T, A> || std::is_same_v<T, B>, int> = 0
>
void doSomething(T const& arg) {
std::cout << arg.data << '\n';
}
int main() {
A a{"Hello "};
B b{"World"};
foo(a);
foo(b);
// foo("something else"); // Doesn't compile
}
Slightly less cluttered with C++20 concepts:
#include <concepts>
template <typename T>
void doSomething(T const& arg) requires (std::same_as<T, A> || std::same_as<T, B>) {
std::cout << arg.data << '\n';
}
You could even over-engineer such a concept into your code-base if this is a common issue you have:
template <typename T, typename ...Types>
concept one_of = (std::same_as<T, Types> || ...);
template <one_of<A, B> T>
void doSomething(T const& arg) {
std::cout << arg.data << '\n';
}
You might use template:
template <typename AorB>
void doSomething(AorB& object_to_modify, string member_value) {
object_to_modify.member_to_add_to = member_value;
// after this 5 to 10 steps that call other methods taking a reference to object_to_modify but do the same thing
method1(object_to_modify);
method2(object_to_modify);
//etc.,
}

How to get a forwarding function to call a base template function that is declared after the forwarding function

I have a case where I need to have a forwarding function defined before a template base function is defined/declared. However, if I call the forwarding function (fwd) that in turn calls the base function test, it says that the base template function is not visible (see the code below). However, if test is called directly, everything works.
So my question is this, is it possible to have the forwarding function make a call to a base template function that is defined later in the compilation unit (before it is used but after the forwarding function)? If not, do I have any options to work around this? I would like to avoid a forward declaration before fwd as that would make use of the library I am developing harder. I think if I could force fwd to be inline it would solve the problem but I have no way of doing that unless a macro is used.
#include <iostream>
#include <vector>
template<typename T, std::enable_if_t<std::is_scalar<T>::value, int> = 0>
void test(const T& t)
{
std::cout << "Scalar" << std::endl;
}
template<typename T>
void fwd(T&& t)
{
test(std::forward<T>(t));
}
template<typename T>
void test(const std::vector<std::vector<T>>& t)
{
std::cout << "vector vector of T" << std::endl;
}
int main(int argc, const char * argv[]) {
test(1); //OK, prints Scalar
fwd(1); //OK, prints Scalar
test(std::vector<std::vector<int>>()); //OK, prints vector vector of T
// Causes compile error: Call to function 'test' that is neither visible in the template definition
// nor found by argument dependent lookup
fwd(std::vector<std::vector<int>>());
return 0;
}
The name test in fwd is a dependent name. It will be resolved into two steps:
Non-ADL lookup examines function declarations ... that are visible from the template definition context.
ADL examines function declarations ... that are visible from either the template definition context or the template instantiation context.
Given that the relative order of test and fwd should not be changed, one possible solution is to use a fake tag struct in the namespace to activate ADL:
namespace my_namespace
{
struct Tag {};
template<typename T, std::enable_if_t<std::is_scalar<T>::value, int> = 0>
void test(const T& t, Tag = Tag{}) {
std::cout << "Scalar" << std::endl;
}
template<typename T>
void fwd(T&& t) {
test(std::forward<T>(t), Tag{});
}
template<typename T>
void test(const std::vector<std::vector<T>>& t, Tag = Tag{}) {
std::cout << "vector vector of T" << std::endl;
}
}
int main() {
my_namespace::test(std::vector<std::vector<int>>()); // OK
my_namespace::fwd(std::vector<std::vector<int>>()); // OK, too
}
Demo
Depending on what test overloads you have, another solution might be to wrap these functions into structs and use template specialization instead of function overloading:
template<class T>
struct Test {
static void op(const T& t) {
std::cout << "Scalar" << std::endl;
}
};
template<typename T>
void fwd(T&& t) {
Test<std::decay_t<T>>::op(std::forward<T>(t));
}
template<class T>
struct Test<std::vector<std::vector<T>>> {
static void op(const std::vector<std::vector<T>>& t) {
std::cout << "vector vector of T" << std::endl;
}
};
int main() {
fwd(1);
fwd(std::vector<std::vector<int>>());
}
Demo

enable_if: minimal example for void member function with no arguments

I am trying to get a better understanding of std::enable_if in C++11 and have been trying to write a minimal example: a class A with a member function void foo() that has different implementations based on the type T from the class template.
The below code gives the desired result, but I am not understanding it fully yet. Why does version V2 work, but not V1? Why is the "redundant" type U required?
#include <iostream>
#include <type_traits>
template <typename T>
class A {
public:
A(T x) : a_(x) {}
// Enable this function if T == int
/* V1 */ // template < typename std::enable_if<std::is_same<T,int>::value,int>::type = 0>
/* V2 */ template <typename U=T, typename std::enable_if<std::is_same<U,int>::value,int>::type = 0>
void foo() { std::cout << "\nINT: " << a_ << "\n"; }
// Enable this function if T == double
template <typename U=T, typename std::enable_if<std::is_same<U,double>::value,int>::type = 0>
void foo() { std::cout << "\nDOUBLE: " << a_ << "\n"; }
private:
T a_;
};
int main() {
A<int> aInt(1); aInt.foo();
A<double> aDouble(3.14); aDouble.foo();
return 0;
}
Is there a better way to achieve the desired result, i.e. for having different implementations of a void foo() function based on a class template parameter?
I know this wont fully answer your question, but it might give you some more ideas and understanding of how you can use std::enable_if.
You could replace your foo member functions with the following and have identical functionality:
template<typename U=T> typename std::enable_if<std::is_same<U,int>::value>::type
foo(){ /* enabled when T is type int */ }
template<typename U=T> typename std::enable_if<std::is_same<U,double>::value>::type
foo(){ /* enabled when T is type double */ }
A while back I gained a pretty good understanding of how enable_if works, but sadly I have forgotten most of its intricacies and just remember the more practical ways to use it.
As for the first question: why V1 doesn't work? SFINAE applies only in overload resolution - V1 however causes error at the point where type A is instantiated, well before foo() overload resolution.
I suppose there are lot's of possible implementations - which is the most appropriate depends on an actual case in question. A common approach would be to defer the part of A that's different for different template types to a helper class.
template <typename T>
class A_Helper;
template <>
class A_Helper<int> {
public:
static void foo( int value ){
std::cout << "INT: " << value << std::endl;
}
};
template <>
class A_Helper<double> {
public:
static void foo( double value ){
std::cout << "DOUBLE: " << value << std::endl;
}
};
template <typename T>
class A {
public:
A( T a ) : a_(a)
{}
void foo(){
A_Helper<T>::foo(a_);
}
private:
T a_;
};
The rest of A can be declared only once in a generic way - only the parts that differ are deferred to a helper. There is a lot of possible variations on that - depending on your requirements...

Non-obtrusive way of getting around an argument dependent lookup ambiguity

Here's my case:
I am trying to use a library that has a type Foo::a, and specifies a Foo::swap as well. Another library that I am consuming has a std::vector<Foo::a> instantiation. I am trying to compile this on Windows using Visual Studio 11.0 and notice that the std::vector::swap maps down to _Swap_adl which does an unqualified swap call.
This is what gets me into issues with ADL and ambiguous function resolutions. Is there some magic that will allow me to use Foo::swap (heck even std::swap :)), without making some "major" change to the libraries that I am consuming (stuff that is short of removing/renaming swap from Foo, etc)?
Edit:
Adding a minimal example that captures what is going on and the error.
#include <iostream>
#include <vector>
namespace Foo
{
class MyType
{
public:
float dummy;
};
template <class T>
void swap(T& a, T& b)
{
T c(a);
a = b;
b = c;
}
}
using namespace Foo;
class MyClass
{
public:
std::vector<MyType> myStructArr;
};
std::vector<MyType> getMyTypeArray()
{
MyType myType;
std::vector<MyType> myTypeArray;
myTypeArray.push_back(myType);
return myTypeArray;
}
namespace std
{
template <>
void swap<MyType*>(MyType*& a, MyType*& b)
{
MyType* c(a);
a = b;
b = c;
}
template <>
void swap<MyType>(MyType& a, MyType& b)
{
MyType c(a);
a = b;
b = c;
}
}
int main(int argc, char* argv[])
{
MyClass m;
MyType myTypeLocal;
std::vector<MyType> myTypeArrayLocal;
myTypeArrayLocal.push_back(myTypeLocal);
//m.myStructArr = myTypeArrayLocal;
m.myStructArr = getMyTypeArray();
return 0;
}
I won't comment on the efficiency of the code, as its something that I just have to work with, but the error log at # http://pastebin.com/Ztea46aC gives a fair idea of what's going on internally. Is this a compiler specific issue, or is there a deeper learning to be gained from this piece of code?
Edit 2:
I've tried specializing for the particular type in question, but that doesn't resolve the ambiguity. Any pointers on why this is so would be helpful as well.
namespace std
{
template <>
void swap<MyType*>(MyType*& a, MyType*& b)
{
MyType* c(a);
a = b;
b = c;
}
template <>
void swap<MyType>(MyType& a, MyType& b)
{
MyType c(a);
a = b;
b = c;
}
}
http://pastebin.com/sMGDZQBZ is the error log from this attempt.
As the error message says, the function call is ambiguous. There are two versions of swap that could be applied: the one in namespace Foo and the one in namespace std. The first is found by argument-dependent lookup. The second is found because vector is defined in std, so sees std::swap (as designed).
This isn't a situation where one declaration hides another; it is simply a set of possible overloads, so the usual ordering rules for selecting an overloaded function apply. The two versions of swap take the same argument types, so there is no preference for one over the other.
Pete's answer explains the situation. Both templates for swap are equally favoured during the overload resolution steps, so the call is ambiguous - in any context where both namespaces are visible. Specialisation is the correct approach to this problem, however based on your errors you've forgotten to remove the offending template Foo::swap - see here for what your code should look like.
Here's what everything looks like - I just replaced the std namespace with the bar namespace.
#include <iostream>
namespace bar { //std namespace
template<typename T>
void swap(T s, T t){ std::cout << "bar swap\n"; }
template<typename S>
struct vec {
S s;
void error() { swap(s, s); }
};}
namespace foo { //your namespace
struct type {};
/*this template is not allowed/not a good idea because of exactly your problem
template<typename T>
void swap(T s, T t){ std::cout << "foo swap\n"; }
*/
//you will have to rename foo::swap to something like this, and make it call
//specialise std::swap for any types used in std containers, so that they called yuor
//renamed foo::swap
template<typename T>
void swap_proxy(T s, T t){ std::cout << "foo swap (via proxy) \n"; }
}
namespace bar {
template<> void swap(foo::type s, foo::type t) { std::cout << "foo swap\n"; }
}
int main()
{
//instead specialise std::swap with your type
bar::vec<foo::type> myVec;
myVec.error();
std::cout << "Test\n";
operator<<(std::cout, "Test\n");
}
All that said I'll try and cook up a templated alternative - however it will call std::swap in std code (it will make foo::swap a worse alternative, so there will be no ambiguity.
This avoids changing the name of swap, but still changes its definition slightly - although
you shouldn't have to tamper with code inside swap, only code that calls will have to cast as explained
#include <iostream>
namespace bar { //std namespace
template<typename T>
void swap(T s, T t){ std::cout << "bar swap\n"; }
template<typename S>
struct vec {
S s;
void error() { swap(s, s); }
};}
namespace foo { //your namespace
// Include this pattern (The infamous Curiously Recurring Template Pattern) in foo namespace
template<template<class> class Derived, typename t>
struct Base : public t { Base(){} Base(Derived<t> d){} };
template<typename t> struct Derived : public Base<Derived, t> {};
template<class t> using UnWrapped = Base<Derived, t>;
template<class t> using Wrapped = Derived<t>;
//we redefine swap to accept only unwrapped t's - meanwhile
//we use wrapped t's in std::containers
template<typename T>
void swap(UnWrapped<T> s, UnWrapped<T> t){ std::cout << "foo swap\n"; }
struct type {
};
}
int main()
{
//use the wrapped type
typedef foo::Wrapped<foo::type> WrappedType;
typedef foo::UnWrapped<foo::type> UnWrappedType;
bar::vec<WrappedType> myVec;
//this is the function which makes the ambiguous call
myVec.error();
//but instead calls bar::swap
//but -- it calls foo swap outside of bar! - any you didn't
//have to change the name of swap, only alter definition slightly
swap(WrappedType(), WrappedType());
//safe outside of bar
swap(UnWrappedType(), UnWrappedType());
//the following no longer works :/
//swap<foo::type>(foo::type(), foo::type());
//instead, yuo will have to cast to UnWrapped<type>
}

visitor template for boost::variant

I would like to use a boost.variant<T0,T1,T2> as a parameter to a template 'Visitor' class which would provide visitor operators as required by the boost.variant visitor mechanism, in this case all returning void i.e.,
void operator()(T0 value);
void operator()(T1 value);
void operator()(T2 value);
The template would also have for each of the types T0... in the variant a corresponding virtual function which by default does nothing. The user is able inherit from the template class and redefine only those virtual functions which he is interested in. This is something akin to the well-known 'Template Method' pattern.
The only solution I have been able to come up with is by wrapping both the boost::variant and the associated visitor in a single template, and accessing them via typedefs. This works okay, however it feels a little clunky. Here's the code:
#include "boost/variant.hpp"
//create specializations of VariantWrapper for different numbers of variants -
//just show a template for a variant with three types here.
//variadic template parameter list would be even better!
template<typename T0, typename T1, typename T2>
struct VariantWrapper
{
//the type for the variant
typedef boost::variant<T0,T1,T2> VariantType;
//The visitor class for this variant
struct Visitor : public boost::static_visitor<>
{
void operator()(T0 value)
{
Process(value);
}
void operator()(T1 value)
{
Process(value);
}
void operator()(T2 value)
{
Process(value);
}
virtual void Process(T0 val){/*do nothing */}
virtual void Process(T1 val){/*do nothing */}
virtual void Process(T2 val){/*do nothing */}
protected:
Visitor(){}
};
typedef Visitor VisitorType;
private:
VariantWrapper(){}
};
The class is then used as follows:
typedef VariantWapper<bool,int,double> VariantWrapperType;
typedef VariantWrapperType::VariantType VariantType;
typedef VariantWrapperType::VisitorType VisitorType;
struct Visitor : public VisitorType
{
void Process(bool val){/*do something*/}
void Process(int val){/*do something*/}
/* this class is not interested in the double value */
};
VariantType data(true);
apply_visitor(Visitor(),data);
As I say, this seems to work okay but I would prefer it if I didn't have to create a special wrapper class to tie the variant and the visitor together. I would prefer to be able just to use a boost.variant directly to instantiate the template visitor class. I've had a look at using type parameters, non-type parameters and template template parameters but nothing seems to suggest itself. Is what I am trying to do not possible? I may be missing something, and would appreciate it if anyone has any input on this.
The code with Boost Variant and virtual dispatching is a little fishy. Especially taking into account that you know what are you interested in processing during the compile-time and there is absolutely no need in creating a virtual table at run-time in order to achieve your goals.
I would recommend you use partial template specialization. Thus, have a default template method that can accept any type in the variant and will do nothing. For those types you are interested in, just specialize template.
Here is an example. We have three types - Foo, Bar and War. We are interested only in the last two types and have a specialization for them. So Foo is being ignored.
#include <iostream>
#include <boost/variant.hpp>
using namespace std;
using namespace boost;
struct Foo {};
struct Bar {};
struct War {};
typedef variant<Foo, Bar, War> Guess;
struct Guesstimator : public boost::static_visitor<void>
{
template <typename T>
void operator () (T) const
{
}
};
template <>
inline void
Guesstimator::operator () <Bar> (Bar) const
{
cout << "Let's go to a pub!" << endl;
}
template <>
inline void
Guesstimator::operator () <War> (War) const
{
cout << "Make love, not war!" << endl;
}
Here is a simple example of the usage:
int
main ()
{
Guess monday;
apply_visitor (Guesstimator (), monday);
War war;
Guess ww2 (war);
apply_visitor (Guesstimator (), ww2);
Bar irishPub;
Guess friday (irishPub);
apply_visitor (Guesstimator (), friday);
}
The output of this program will be:
Make love, not war!
Let's go to a pub!
Here is another solution. We create a default visitor ignoring everything, except what you have specified in a type list. It is not that convenient because you have to specify a list of types twice - once in a type list and then in each processing method (operator). Plus, the generic template, in fact, will be inheriting your visitor. But nevertheless, here we go:
#include <cstddef>
#include <iostream>
#include <boost/variant.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/utility/enable_if.hpp>
// Generic visitor that does magical dispatching of
// types and delegates passes down to your visitor only
// those types specified in a type list.
template <typename Visitor, typename TypeList>
struct picky_visitor :
public boost::static_visitor<void>,
public Visitor
{
template <typename T>
inline void
operator () (T v, typename boost::enable_if< typename boost::mpl::contains< TypeList, T >::type >::type *dummy = NULL) const
{
Visitor::operator () (v);
}
template <typename T>
inline void
operator () (T v, typename boost::disable_if<typename boost::mpl::contains< TypeList, T >::type >::type *dummy = NULL) const
{
}
};
// Usage example:
struct nil {};
typedef boost::variant<nil, char, int, double> sql_field;
struct example_visitor
{
typedef picky_visitor< example_visitor, boost::mpl::vector<char, int> > value_type;
inline void operator () (char v) const
{
std::cout << "character detected" << std::endl;
}
inline void operator () (int v) const
{
std::cout << "integer detected" << std::endl;
}
};
int
main ()
{
example_visitor::value_type visitor;
sql_field nilField;
sql_field charField ('X');
sql_field intField (1986);
sql_field doubleField (19.86);
boost::apply_visitor (visitor, nilField);
boost::apply_visitor (visitor, charField);
boost::apply_visitor (visitor, intField);
boost::apply_visitor (visitor, doubleField);
}
As time passes new and interesting libraries develop. This question is old, but since then there is a solution that to me personally is far more superior to the ones that have been given so far.
The excellent Mach7 library which allows unprecedented matching (and therefore visiting) capabilities. It is written by Yuriy Solodkyy, Gabriel Dos Reis and Bjarne Stroustrup himself. For the ones stumbling on this question, here is an example taken from the README:
void print(const boost::variant<double,float,int>& v)
{
var<double> d; var<float> f; var<int> n;
Match(v)
{
Case(C<double>(d)) cout << "double " << d << endl; break;
Case(C<float> (f)) cout << "float " << f << endl; break;
Case(C<int> (n)) cout << "int " << n << endl; break;
}
EndMatch
}
I am working with it now and so far it is a real pleasure to use.
Tom, I believe that your question makes much sense in a particular context. Say that you want to store visitors of multiple types in a vector, but you can't because they are all of different types. You have a few choices: use variant again to store visitors, use boost.any, or use virtual functions. I think that virtual functions are an elegant solution here, but certainly not the only one.
Here is how it goes.
First, let's use some variant; bool, int, and float will do.
typedef boost::variant<bool, int, float> variant_type;
Then comes the base class, more or less as you had it.
template
struct Visitor : public boost::static_visitor<>
{
void operator()(T0 value)
{
Process(value);
}
void operator()(T1 value)
{
Process(value);
}
void operator()(T2 value)
{
Process(value);
}
virtual void Process(T0 val){ std::cout << "I am Visitor at T0" << std::endl; }
virtual void Process(T1 val){ std::cout << "I am Visitor at T1" << std::endl; }
virtual void Process(T2 val){ std::cout << "I am Visitor at T2" << std::endl; }
protected:
Visitor(){}
};
Next, we have two specific variants.
template
struct Visitor1 : public Visitor
{
void Process(T0 val){ std::cout << "I am Visitor1 at T0" << std::endl; }
void Process(T2 val){ std::cout << "I am Visitor1 at T2" << std::endl; }
};
template
struct Visitor2 : public Visitor
{
void Process(T1 val){ std::cout << "I am Visitor2 at T1" << std::endl; }
void Process(T2 val){ std::cout << "I am Visitor2 at T2" << std::endl; }
};
Finally, we can make a single vector of different variants:
int main() {
variant_type data(1.0f);
std::vector*> v;
v.push_back(new Visitor1());
v.push_back(new Visitor2());
apply_visitor(*v[0],data);
apply_visitor(*v[1],data);
data = true;
apply_visitor(*v[0],data);
apply_visitor(*v[1],data);
return 0;
}
And here is the output:
I am Visitor1 at T2
I am Visitor2 at T2
I am Visitor1 at T0
I am Visitor at T0
If for some reason I needed to have different variants in one container, I would surely consider this solution. I would also think how much worse/better would it be to actually stick the visitors into another variant. The nice thing about using inheritance is that it is extensible post factum: you can always inherit from a class, but once a variant is set, you can't change it without actually touching the existing code.