I want to somehow merge templates like these into one:
template <class Result, class T1, class T2>
class StupidAdd
{
public:
T1 _a; T2 _b;
StupidAdd(T1 a, T2 b):_a(a),_b(b) {}
Result operator()() { return _a+_b; }
};
template <class Result, class T1, class T2>
class StupidSub
{
public:
T1 _a; T2 _b;
StupidSub(T1 a, T2 b):_a(a),_b(b) {}
Result operator()() { return _a-_b; }
};
(followed by the same code for Mul, Div, etc) where all the code is the same,
except for the actual "+", "-" (and "StupidAdd", "StupidSub", etc).
These Stupid "functors" are then used by another template.
How can I avoid the repetition, WITHOUT the preprocessor?
(The reason I got into templates was to avoid the preprocessor)
That is, how can I pass arithmetic operators into a template?
Maybe you could use std::plus<T>, std::minus<T>, std::multiplies<T> and std::divides<T>. However, these will work only if both operands are of the same type, or probably if the left one can be converted to the type of the first one.
I don't see any way to achieve what you're trying to do, except by using the preprocessor. Any good reasons for not wanting macros ?
If you want to make sure the return type is large enough to contains the result, you could do something along this way:
#include <functional>
#include <boost/mpl/if_.hpp>
// Metafunction returning the largest type between T and U
// Might already exist in Boost but I can't find it right now...maybe
// boost::math::tools::promote_args
template <typename T, typename U>
struct largest :
boost::mpl::if_<
boost::mpl::bool_<(sizeof(T) > sizeof(U))>,
T,
U
>
{};
template <typename T, typename U, template <typename S> class Op>
struct Foo
{
typedef typename largest<T, U>::type largeType;
largeType bar(const T & t, const U & u)
{
return Op<largeType>()(t, u); // Applies operator+
}
};
int main()
{
Foo<int, double, std::plus> f;
double d = f.bar(12, 13.0); // takes int and double, returns double
}
Here, I used Boost MPL to write the largest metafunction, but you could write your own if metafunction if you cannot use Boost (class template parameterized by two types and a bool, specialized for true and false).
To determine the return type of an expression, you could also have a look at boost::result_of which, if I understand correctly, is equivalent to the upcoming decltype operator in C++0x.
Thanks Luc, this is very cool.
I finally did it in a simpler way:
#include <functional>
template <
class Result,
class T1,
class T2,
template <class ReturnType> class BinaryOp>
class Stupido
{
public:
T1 _a; T2 _b;
Stupido(T1 a, T2 b):_a(a),_b(b) {}
Result operator()() { return BinaryOp<Result>()((Result)_a,(Result)_b); }
};
And used the "plus", "minus" when instantiating Stupido.
The cast to "Result" was enough for my needs (int + double => double + double => double)
I think there's an improvement to OldCoder's solution:
#include <functional>
template <class Result,
template <class Result> class BinaryOp>
struct Stupido
{
template <typename T1, typename T2>
Result operator()(const T1& a, const T2& b) { return BinaryOp<Result>()((Result)a,(Result)b); }
};
This way the call can be made as:
Stupido<int, std::plus > stup;
int result = stup(3.0f, 2.0);
and the same function object can be used with multiple operands, so it could be passed in to a std::transform call.
I believe there must be a way to remove one Result from the template declaration, but I am unable to find it.
I'd use the C++ 0x decltype and the new definition of auto. You'll still need to define the classes, but using these, you can do a nicer job of defining them. They'll still be about as much work to define, but at least using them will be considerably cleaner. In particular, you can use decltype/auto to deduce the correct return type instead of having to specify it explicitly.
These are available with a fair number of recent compilers -- Intel C++, g++, Comeau, the beta of VC++ 2010, and even the most recent iteration of Borland/Inprise/Embarcadero/this week's new name.
Related
I have generic class in c++
template<typename A>
struct series {
A member;
}
template<typename A,typename B,typename C>
series <C> & operator + (A first, const B& second) {
return first+second;
}
I need to return type that is implicit conversion of type A and type B.
Fox example :
double a + int b → implicit conversion is double
how can I do that, because C cannot be determined like this
I was trying something with decltype and typedef but it didn't work
Thanks in advance
You can use C++11 trailing return types with decltype:
template<typename A,typename B>
auto operator+(A first, const B& second) -> decltype(first+second) {
return first+second;
}
The standard library provides a number of templates for situations like this. For the moment, let's deal with the really simple case:
template <class T, class U>
returnType operator+(T t, U u) {
return t + u;
}
So what should we use for returnType? In this case, we can use std::common_type, which tells us the common type to which both its operand types will be converted when used in an expression together.
template <class T, class U>
typename std::common_type<T, U>::type add(T t, U u) {
return t + u;
}
So, if we passed this an int and a double, the return type would be double.
In most cases, the result type is pretty obvious, but in a few cases, the result can be...interesting, to put it mildly. For example, on an implementation that used 16 bits for both short and int (like many MS-DOS compilers did), it's entirely possible that unsigned short + int could have a common type of long.
I am trying to write a class template that uses a parameter-pack and implements a member function for each type contained in the parameter-pack.
This is what I have so far:
template <typename...T>
class Myclass {
public:
void doSomething((Some_Operator_to_divorce?) T) {
/*
* Do Something
*/
std::cout << "I did something" << std::endl;
}
};
My goal is to have a class template that can be used in the following way:
Myclass<std::string, int, double> M;
M.doSomething("I am a String");
M.doSomething(1234);
M.doSomething(0.1234);
Where the class template mechanism will create an implementation for a doSomething(std::string x), a doSomething(int x) and a doSomething(double x) member function but not a doSomething(std::string x, int i, double f) member function.
I found a lot of examples in the web on the usability of parameter-packs, but I could not figure out if it can be used for my purpose, or if I totally misunderstood for what a parameter-pack can be used.
I thought that I need to unpack the parameter-pack but, after reading a lot of examples about unpacking parameter packs, I believe that this is not the right choice and it has a complete different meaning.
So, therefore, I am looking for a operation to "divorce" a parameter-pack.
There is no "operator" specifically that supports this, but what you're requesting can be done in a few different ways, depending on your requirements.
The only way to "extract" T types from a parameter pack of a class template with the purpose of implementing an overload-set of functions is to implement it using recursive inheritance, where each instance extracts one "T" type and implements the function, passing the rest on to the next implementation.
Something like:
// Extract first 'T', pass on 'Rest' to next type
template <typename T, typename...Rest>
class MyClassImpl : public MyClassImpl<Rest...>
{
public:
void doSomething(const T&) { ... }
using MyClassImpl<Rest...>::doSomething;
};
template <typename T>
class MyClassImpl<T> // end-case, no more 'Rest'
{
public:
void doSomething(const T&) { ... }
};
template <typename...Types>
class MyClass : public MyClassImpl<Types...>
{
public:
using MyClassImpl<Types...>::doSomething;
...
};
This will instantiate sizeof...(Types) class templates, where each one defines an overload for each T type.
This ensures that you get overload semantics -- such that passing an int can call a long overload, or will be ambiguous if there are two competing conversions.
However, if this is not necessary, then it'd be easier to enable the function with SFINAE using enable_if and a condition.
For exact comparisons, you could create an is_one_of trait that only ensures this exists if T is exactly one of the types. In C++17, this could be done with std::disjunction and std::is_same:
#include <type_traits>
// A trait to check that T is one of 'Types...'
template <typename T, typename...Types>
struct is_one_of : std::disjunction<std::is_same<T,Types>...>{};
Alternatively, you may want this to only work if it may work with convertible types -- which you might do something like:
template <typename T, typename...Types>
struct is_convertible_to_one_of : std::disjunction<std::is_convertible<T,Types>...>{};
The difference between the two is that if you passed a string literal to a MyClass<std::string>, it will work with the second option since it's convertible, but not the first option since it's exact. The deduced T type from the template will also be different, with the former being exactly one of Types..., and the latter being convertible (again, T may be const char*, but Types... may only contain std::string)
To work this together into your MyClass template, you just need to enable the condition with SFINAE using enable_if:
template <typename...Types>
class MyClass
{
public:
// only instantiates if 'T' is exactly one of 'Types...'
template <typename T, typename = std::enable_if_t<is_one_of<T, Types...>::value>>
void doSomething(const T&) { ... }
// or
// only instantiate if T is convertible to one of 'Types...'
template <typename T, typename = std::enable_if_t<is_convertible_to_one_of<T, Types...>::value>>
void doSomething(const T&) { ... }
};
Which solution works for you depends entirely on your requirements (overload semantics, exact calling convension, or conversion calling convension)
Edit: if you really wanted to get complex, you can also merge the two approaches... Make a type trait to determine what type would be called from an overload, and use this to construct a function template of a specific underlying type.
This is similar to how variant needs to be implemented, since it has a U constructor that considers all types as an overload set:
// create an overload set of all functions, and return a unique index for
// each return type
template <std::size_t I, typename...Types>
struct overload_set_impl;
template <std::size_t I, typename T0, typename...Types>
struct overload_set_impl<I,T0,Types...>
: overload_set_impl<I+1,Types...>
{
using overload_set_impl<I+1,Types...>::operator();
std::integral_constant<std::size_t,I> operator()(T0);
};
template <typename...Types>
struct overload_set : overload_set_impl<0,Types...> {};
// get the index that would be returned from invoking all overloads with a T
template <typename T, typename...Types>
struct index_of_overload : decltype(std::declval<overload_set<Types...>>()(std::declval<T>())){};
// Get the element from the above test
template <typename T, typename...Types>
struct constructible_overload
: std::tuple_element<index_of_overload<T, Types...>::value, std::tuple<Types...>>{};
template <typename T, typename...Types>
using constructible_overload_t
= typename constructible_overload<T, Types...>::type;
And then use this with the second approach of having a function template:
template <typename...Types>
class MyClass {
public:
// still accept any type that is convertible
template <typename T, typename = std::enable_if_t<is_convertible_to_one_of<T, Types...>::value>>
void doSomething(const T& v)
{
// converts to the specific overloaded type, and call it
using type = constructible_overload_t<T, Types...>;
doSomethingImpl<type>(v);
}
private:
template <typename T>
void doSomethingImpl(const T&) { ... }
This last approach does it two-phase; it uses the first SFINAE condition to ensure it can be converted, and then determines the appropriate type to treat it as and delegates it to the real (private) implementation.
This is much more complex, but can achieve the overload-like semantics without actually requiring recursive implementation in the type creating it.
I have the following snipped of code, which does not compile.
#include <iostream>
struct A {
void foo() {}
};
struct B : public A {
using A::foo;
};
template<typename U, U> struct helper{};
int main() {
helper<void (A::*)(), &A::foo> compiles;
helper<void (B::*)(), &B::foo> does_not_compile;
return 0;
}
It does not compile since &B::foo resolves to &A::foo, and thus it cannot match the proposed type void (B::*)(). Since this is part of a SFINAE template that I am using to check for a very specific interface (I'm forcing specific argument types and output types), I would like for this to work independently of inheritances, while keeping the check readable.
What I tried includes:
Casting the second part of the argument:
helper<void (B::*)(), (void (B::*)())&B::foo> does_not_compile;
This unfortunately does not help as the second part is now not recognized as a constant expression, and fails.
I've tried assigning the reference to a variable, in order to check that.
constexpr void (B::* p)() = &B::foo;
helper<void (B::* const)(), p> half_compiles;
This code is accepted by clang 3.4, but g++ 4.8.1 rejects it, and I have no idea on who's right.
Any ideas?
EDIT: Since many comments are asking for a more specific version of the problem, I'll write it here:
What I'm looking for is a way to explicitly check that a class respects a specific interface. This check will be used to verify input arguments in templated functions, so that they respect the contract that those functions require, so that compilation stops beforehand in case the class and a function are not compatible (i.e. type traits kind of checking).
Thus, I need to be able to verify return type, argument type and number, constness and so on of each member function that I request. The initial question was the checking part of the bigger template that I'm using to verify matches.
A working solution to your problem as posted at https://ideone.com/mxIVw3 is given below - see also live example.
This problem is in a sense a follow-up of Deduce parent class of inherited method in C++. In my answer, I defined a type trait member_class that extracts a class from a given pointer to member function type. Below we use some more traits to analyse and then synthesize back such a type.
First, member_type extracts the signature, e.g. void (C::*)() gives void():
template <typename M> struct member_type_t { };
template <typename M> using member_type = typename member_type_t <M>::type;
template <typename T, typename C>
struct member_type_t <T C::*> { using type = T;};
Then, member_class extracts the class, e.g. void (C::*)() gives C:
template<typename>
struct member_class_t;
template<typename M>
using member_class = typename member_class_t <M>::type;
template<typename R, typename C, typename... A>
struct member_class_t <R(C::*)(A...)> { using type = C; };
template<typename R, typename C, typename... A>
struct member_class_t <R(C::*)(A...) const> { using type = C const; };
// ...other qualifier specializations
Finally, member_ptr synthesizes a pointer to member function type given a class and a signature, e.g. C + void() give void (C::*)():
template <typename C, typename S>
struct member_ptr_t;
template <typename C, typename S>
using member_ptr = typename member_ptr_t <C, S>::type;
template <typename C, typename R, typename ...A>
struct member_ptr_t <C, R(A...)> { using type = R (C::*)(A...); };
template <typename C, typename R, typename ...A>
struct member_ptr_t <C const, R(A...)> { using type = R (C::*)(A...) const; };
// ...other qualifier specializations
The two previous traits need more specialization for different qualifiers to be more generic, e.g. const/volatile or ref-qualifiers. There are 12 combinations (or 13 including data members); a complete implementation is here.
The idea is that any qualifiers are transferred by member_class from the pointer-to-member-function type to the class itself. Then member_ptr transfers qualifiers from the class back to the pointer type. While qualifiers are on the class type, one is free to manipulate with standard traits, e.g. add or remove const, lvalue/rvalue references, etc.
Now, here is your is_foo test:
template <typename T>
struct is_foo {
private:
template<
typename Z,
typename M = decltype(&Z::foo),
typename C = typename std::decay<member_class<M>>::type,
typename S = member_type<M>
>
using pattern = member_ptr<C const, void()>;
template<typename U, U> struct helper{};
template <typename Z> static auto test(Z z) -> decltype(
helper<pattern<Z>, &Z::foo>(),
// All other requirements follow..
std::true_type()
);
template <typename> static auto test(...) -> std::false_type;
public:
enum { value = std::is_same<decltype(test<T>(std::declval<T>())),std::true_type>::value };
};
Given type Z, alias template pattern gets the correct type M of the member pointer with decltype(&Z::foo), extracts its decay'ed class C and signature S, and synthesizes a new pointer-to-member-function type with class C const and signature void(), i.e. void (C::*)() const. This is exactly what you needed: it's the same with your original hard-coded pattern, with the type Z replaced by the correct class C (possibly a base class), as found by decltype.
Graphically:
M = void (Z::*)() const -> Z + void()
-> Z const + void()
-> void (Z::*)() const == M
-> SUCCESS
M = int (Z::*)() const& -> Z const& + int()
-> Z const + void()
-> void (Z::*)() const != M
-> FAILURE
In fact, signature S wasn't needed here, so neither was member_type. But I used it in the process, so I am including it here for completeness. It may be useful in more general cases.
Of course, all this won't work for multiple overloads, because decltype doesn't work in this case.
If you simply want to check the existence of the interface on a given type T, then there're better ways to do it. Here is one example:
template<typename T>
struct has_foo
{
template<typename U>
constexpr static auto sfinae(U *obj) -> decltype(obj->foo(), bool()) { return true; }
constexpr static auto sfinae(...) -> bool { return false; }
constexpr static bool value = sfinae(static_cast<T*>(0));
};
Test code:
struct A {
void foo() {}
};
struct B : public A {
using A::foo;
};
struct C{};
int main()
{
std::cout << has_foo<A>::value << std::endl;
std::cout << has_foo<B>::value << std::endl;
std::cout << has_foo<C>::value << std::endl;
std::cout << has_foo<int>::value << std::endl;
return 0;
}
Output (demo):
1
1
0
0
Hope that helps.
Here's a simple class that passes your tests (and doesn't require a dozen of specializations :) ). It also works when foo is overloaded. The signature that you wish to check can also be a template parameter (that's a good thing, right?).
#include <type_traits>
template <typename T>
struct is_foo {
template<typename U>
static auto check(int) ->
decltype( static_cast< void (U::*)() const >(&U::foo), std::true_type() );
// ^^^^^^^^^^^^^^^^^^^
// the desired signature goes here
template<typename>
static std::false_type check(...);
static constexpr bool value = decltype(check<T>(0))::value;
};
Live example here.
EDIT :
We have two overloads of check. Both can take a integer literal as a parameter and because the second one has an ellipsis in parameter list it'll never be the best viable in overload resolution when both overloads are viable (elipsis-conversion-sequence is worse than any other conversion sequence). This lets us unambiguously initialize the value member of the trait class later.
The second overload is only selected when the first one is discarded from overload set. That happens when template argument substitution fails and is not an error (SFINAE).
It's the funky expression on the left side of comma operator inside decltype that makes it happen. It can be ill-formed when
the sub-expression &U::foo is ill-formed, which can happen when
U is not a class type, or
U::foo is inaccesible, or
there is no U::foo
the resulting member pointer cannot be static_cast to the target type
Note that looking up &U::foo doesn't fail when U::foo itself would be ambiguous. This is guaranteed in certain context listed in C++ standard under 13.4 (Address of overloaded function, [over.over]). One such context is explicit type conversion (static_cast in this case).
The expression also makes use of the fact that T B::* is convertible to T D::* where D is a class derived from B (but not the other way around). This way there's no need for deducing the class type like in iavr's answer.
value member is then initialized with value of either true_type or false_type.
There's a potential problem with this solution, though. Consider:
struct X {
void foo() const;
};
struct Y : X {
int foo(); // hides X::foo
};
Now is_foo<Y>::value will give false, because name lookup for foo will stop when it encounters Y::foo. If that's not your desired behaviour, consider passing the class in which you wish to perform lookup as a template parameter of is_foo and use it in place of &U::foo.
Hope that helps.
I suggest using decltype to generically determine the type of the member function pointers:
helper<decltype(&A::foo), &A::foo> compiles;
helper<decltype(&B::foo), &B::foo> also_compiles;
It may seem like a DRY violation, but repeating the name is fundamentally no worse than specifying the type separately from the name.
Consider the following (invalid) code sample:
// a: base template for function with only one parameter
template<typename T>
void f(T t) { }
// b: base tempalte for function with two parameters
template<typename T1, typename T2>
void f(T1 t1, T2 t2) { }
// c: specialization of a for T = int
template<>
void f<int>(int i) { }
// d: specialization for b with T1 = int - INVALID
template<typename T2>
void f<int, T2>(int i, T2 t2) { }
int main() {
f(true); // should call a
f(true, false); // should call b
f(1); // should call c
f(1, false); // should call d
}
I've read this walk-through on why, in general, partial function template specializations won't work, and I think I understand the basic reasoning: there are cases where function template specializations and overloading would make certain calls ambiguous (there are good examples in the article).
However, is there a reason why this specific example wouldn't work, other than "the standard says it shouldn't"? Does anything change if I can guarantee (e.g. with a static_assert) that the base template is never instantiated? Is there any other way to achieve the same effect?
What I actually want to achieve is to create an extendable factory method
template<typename T>
T create();
which also has a few overloads taking input parameters, e.g.
template<typename T, typename TIn>
T create(TIn in);
template<typename T, typename TIn1, typename TIn2>
T create(TIn1 in1, TIn2 in2);
In order to ensure that all necessary factory methods are present, I use static_assert in the function base templates, so that a compiler error is generated if the create method is called with template arguments for which no specialization has been provided.
I want these to be function templates rather than class templates because there will be quite a lot of them, and they will all use input from the same struct hierarchy, so instantiating 10 factories instead of one comes with some overhead that I'd like to avoid (not considering the fact that the code gets much easier to understand this way, if I can just get it to work...).
Is there a way to get around the problem outlined in the first half of this post, in order to achieve what I've tried to get at with the second half?
In response to iavr:
I could do this with plain overloading, which would (given the templates above) give something like
template<typename TIn2>
A create(bool, TIn2);
template<typename TIn2>
A create(int, TIn2);
if I need two different partial specializations with T = A, TIn1 specified and TIn2 still unspecified. This is a problem, since I have some cases (which are really text-book cases for meta-programming and templates) where I know that, for example, one of the arguments will be a std::string, and the other will be of some type that has a property fields and a property grids, which are of types std::vector<field> and std::vector<grid> respectively. I don't know all the types that will ever be supplied as the second argument - I know for sure that there will be more of them than the ones I currently have implemented - but the implementation of the method will be exactly the same.
While writing up this update, I think I've figured out a way to redesign the implementations so that there is no need for the partial specialization - basically, I do the following to cover the case outlined above:
template<>
A create<A, std::vector<field>, std::vector<grid>>(std::vector<field> fs, std::vector<grid> gs);
and then I have to change the calling signature slightly, but that's OK.
I share your concerns that maybe in this particular case there would be no problem having function template partial specializations, but then again, that's the way it is, so what would be your problem using plain overloading?
// a: base template for function with only one parameter
template<typename T>
void f(T t) { }
// b: base template for function with two parameters
template<typename T1, typename T2>
void f(T1 t1, T2 t2) { }
// c: specialization of a for T = int
void f(int i) { }
// d: specialization for b with T1 = int
template<typename T2>
void f(int i, T2 t2) { }
This also takes less typing and I get this is why you don't want to use function objects (which would have partial specialization).
Here is a simple workaround using a class template specialization:
template <typename, typename...>
struct Creator;
template <typename T, typename TIn>
struct Creator<T, TIn>
{
T call(TIn in)
{
// ...
}
};
template<typename T, typename TIn1, typename TIn2>
struct Creator<T, TIn1, TIn2>
{
T call(TIn1 in1, TIn2 in2)
{
// ...
}
};
template <typename R, typename... Arguments>
R Create(Arguments&&... arguments)
{
return Creator<R, Arguments...>::call(std::forward<Arguments>(arguments)...);
}
If you don't want overloading, and want to be able to specialize from a separate file, then I think you should base it on the solution on the link from your question. It involves making a static method on a class that you specialize. From my reading of the question, you're only interested in specializing on the T, not on the number of arguments, which you intend to forward. In C++11, you can do the following:
#include <iostream>
#include <utility>
using namespace std;
template<typename T>
struct factory_impl;
// Left unspecified for now (which causes compliation failure if
// not later specialized
template<typename T, typename... Args>
T create(Args&&... args)
{
return factory_impl<T>::create(std::forward<Args>(args)...);
}
// Note, this can be specified in a header in another translation
// unit. The only requirement is that the specialization
// be defined prior to calling create with the correct value
// of T
template<>
struct factory_impl<int>
{
// int can be constructed with 0 arguments or 1 argument
static int create(int src = 0)
{
return src;
}
};
int main(int argc, char** argv)
{
int i = create<int>();
int j = create<int>(5);
// double d = create<double>(); // Fails to compile
std::cout << i << " " << j << std::endl;
return 0;
}
Live example http://ideone.com/7a3uRZ
Edit: In response to your question, you could also make create a member function of a class, and pass along some of that data with the call or take action before or after
struct MyFactory
{
template<typename T, typename... Args>
T create(Args&&... args)
{
T ret = factory_impl<T>::create(data, std::forward<Args>(args)...);
// do something with ret
return ret;
}
Foo data; // Example
};
If I have,
template<typename T1, typename T2, int N>
class X {};
Is there any way, that I can know class X has 3 template arguments ?
Use case in brief: There are two library classes ptr<T> (for normal pointer) and ptr_arr<T,N> (for pointer to array). These two are interacting with another class in following way:
template<typename T>
void Clear(const T &obj)
{
if(T::Args == 1) destroy(obj);
else destroy_arr(obj);
}
So, I thought if we have some handy way of knowing the number of parameters, it would make it easy. However, I learn that I need to change my business logic as there cannot be such way.
There is no standard way to do this (unless you use variadic sizeof(Args...) in C++0x) but that's beside the point -- the question is wrong.
Use overload resolution.
template <typename T>
void clear (ptr<T> & obj) {
destroy (obj);
}
template <typename T, int N>
void clear (ptr_arr<T,N> & obj) {
destroy_arr (obj);
}
You can use the mpl::template_arity (undocumented)
http://www.boost.org/doc/libs/1_40_0/boost/mpl/aux_/template_arity.hpp
There is no way to do this. Imagine the amount of overloads.
template<int> struct A;
template<bool> struct B;
template<char> struct C;
template<typename> struct D;
template<D<int>*> struct E;
template<D<bool>*> struct F;
template<typename, int> struct G;
// ...
For each of that, you would need a different template to accept them. You cannot even use C++0x's variadic templates, because template parameter packs only work on one parameter form and type (for example, int... only works for a parameter pack full of integers).