I am writing a library that I would like to keep header-only. In the code I have something like this:
// Wrapper.h
#ifndef INCLUDED_WRAPPER_H
#define INCLUDED_WRAPPER_H
namespace quux {
template <typename T, typename U>
class Wrapper
{
T m_t;
U m_u;
public:
Wrapper(T const & t, U const & u) : m_t(t), m_u(u) { }
// ...
};
} // namespace quux
#endif // INCLUDED_WRAPPER_H
// Foo.h
#ifndef INCLUDED_FOO_H
#define INCLUDED_FOO_H
#include <type_traits>
#include "Wrapper.h"
namespace quux {
// if some type is special, then there will be a specialization of this
// struct derived from std::true_type
template <typename T> struct is_special : std::false_type { };
class Foo
{
template <typename T>
Wrapper<Foo, T> impl(T const & t, std::true_type ) const
{
return Wrapper<Foo, T>(*this, t);
}
template <typename T>
T const & impl(T const & t, std::false_type ) const;
{
return t;
}
public:
template <typename T>
auto operator()(T const & t) const // using automatic return type deduction
{
return impl(t, is_special<T>());
}
};
#if 1
Foo const foo;
#else
template <typename T>
auto foo(T const & t) // using automatic return type deduction
{
return Foo()(t);
}
#endif
} // namespace quux
#endif // INCLUDED_FOO_H
I see two different ways to have a callable entity with the name "quux::foo": a constant object named foo (the #if 1 - branch) or a function named foo that forwards its arguments to a Foo-object (the #else-branch). Which version should I prefer? A const Object has internal linkage so there are no linker errors if the header is included in multiple translation units. Are there any salient differences between the two approaches?
As you are calling a function, and your function object has no state, I would go with the function interface.
First, because functions can be overloaded, while function objects cannot outside of the body of the function object. You may wish to enable ADL extensions to your function.
Second because function objects are wierd. They cannot be converted to function pointers (in your case for no good reason), for example (note you can fix that with more boilerplate). Weird solutions are only a good idea when simple solutions are insufficient: in this case the simple perfect forwarding function is simpler.
Finally you might want to make your functions perfect forward, and have T&& rvalues give functions that return T at the outermost API level. This enables lifetime extension of temporaries to pass through your functions.
Related
I would like to check if there exist a member function with signature fit to a parameter pack. I began with the known SFINAE concept, while trying to extend it for considering also a parameters pack. But at this point I found that I don't know how to do it.
I try to do something like this:
// Note: T object may have several functions with the name foo, but with different signatures.
// a function foo also can be a template one with variadic parameters pack.
template<typename T, typename...Args>
class HAS_FUNCTION_FOO
{
template<typename U>
static bool test(decltype(&U::foo));
template<typename U>
static float test(...);
public:
static constexpr bool value = std::is_integral<decltype(test<T>(Args...))>::value;
//-------------------------------------------------------------^^^^^^^^^
// how to do it?
};
I would like to use it for declaring specific object at compile time - something like this:
class Bar
{
public:
template<typename T, typename...Args>
void doSomthing(T* p, Args&&...parameters)
{
// get correct object type:
// if T has a function called foo with parameters fits for pack, then declare A, o.w declare B.
using ObjType = typename std::conditional<HAS_FUNCTION_FOO<T, Args>::value, A, B>::type;
// compute
ObjType::doSomthing(p, std::forward<Args>(parameters)...);
}
private:
struct A
{
template<typename T, typename...Args>
static void doSomthing(T* p, Args&&...parameters)
{
p->foo(std::forward<Args>(parameters)...);
}
};
struct B
{
template<typename T, typename...Args>
static void doSomthing(T* p, Args&&...parameters)
{
// do something else
}
};
};
Something like this, perhaps:
template<typename T, typename...Args>
class HAS_FUNCTION_FOO
{
template <typename U>
static std::true_type test(
typename std::enable_if<sizeof(
decltype(std::declval<U>().foo(std::declval<Args>()...))*) != 0>::type*
);
template <typename U>
static std::false_type test(...);
public:
static constexpr bool value = decltype(test<T>(nullptr))::value;
};
Demo
I have a C++11 template that can be specialized with an arbitrary type parameter.
template<class ElementType>
class Foo
How do I declare a constructor that appears for the compiler's consideration only when ElementType is e.g. const uint8_t?
That is, I have a bunch of constructors that are generic over any ElementType, but I also want to have constructors that are only considered when ElementType is specialized in a particular way. (Allowing those constructors to be selected for other types would be unsafe.)
So far std::enable_if examples that I've found have been conditional on the types of the arguments of the constructors.
template<class ElementType>
struct Foo
{
template <typename T = ElementType>
Foo(typename std::enable_if<!std::is_same<T, const uint8_t>{}>::type* = nullptr) {}
template <typename T = ElementType>
Foo(typename std::enable_if<std::is_same<T, const uint8_t>{}>::type* = nullptr) {}
};
int main()
{
Foo<int> a{}; // ok, calls first constructor
Foo<const uint8_t> b{}; // ok, calls second constructor
}
wandbox example
You can break the class into two classes. The derived class' purpose is to be able to specialize constructors for different types. E.g.:
#include <cstdio>
#include <cstdint>
template<class ElementType>
struct Foo_
{
Foo_() { std::printf("%s\n", __PRETTY_FUNCTION__); }
};
template<class ElementType>
struct Foo : Foo_<ElementType>
{
using Foo_<ElementType>::Foo_; // Generic version.
};
template<>
struct Foo<uint8_t> : Foo_<uint8_t>
{
Foo() { std::printf("%s\n", __PRETTY_FUNCTION__); } // Specialization for uint8_t.
};
int main(int ac, char**) {
Foo<int8_t> a;
Foo<uint8_t> b;
}
The benefit of using the derived class here compared to enable_if is that:
The class can be partially specialized.
Only one specialization of the class is chosen for particular template parameters, rather than a set of constructors. When adding specializations for new types the existing enable_if expressions may need to be changed to make them more restrictive to avoid function overload set resolution ambiguity.
The following is a mockup code that I wrote to experiment with trailing return types in a CRTP setup.
#include <iostream>
#include <memory>
#include <utility>
using namespace std;
struct t_aspect{
struct t_param1 {};
};
// Generic Selector
template <typename t_detail>
struct Select;
template <>
struct Select<t_aspect::t_param1> {
using typeof = t_aspect::t_param1;
};
//Base CRTP class
template<typename dclas>
class CrtpB
{
public:
template<typename T1>
auto func1() -> // What should be here?
{
return(static_cast<dclas*>(this)->func1<T1>());
}
};
//Derived CRTP class
class CrtpD : public CrtpB<CrtpD>
{
private:
uint32_t param1 = 0;
private:
auto func1(const t_aspect::t_param1&) -> uint32_t
{
return(param1);
}
public:
static auto create() -> unique_ptr<CrtpB>
{
return(unique_ptr<CrtpD>(new CrtpD));
}
template<typename T1>
auto func1() -> decltype(func1(typename Select<T1>::typeof()))
{
return(func1(typename Select<T1>::typeof()));
}
};
int main()
{
auto crtp = CrtpD::create();
auto parm = crtp->func1<t_aspect::t_param1>();
return 0;
}
I would like some help in deciphering what should be the trailing return type of func1 in CrtpB.
I have tried using
decltype(static_cast<dclas*>(this)->func1<T1>())
but this does not work. I have also tried writing a helper function based on a solution found in Inferring return type of templated member functions in CRTP.
template <typename D, typename T>
struct Helpr {
typedef decltype(static_cast<D*>(0)->func1<T>()) type;
};
But this does not work either.
dclas is an incomplete type when the base class is instantiated. You need to do two things to make this work:
Defer the checking of the type of func1<T1>() until the type is complete
Use the template keyword on the dependent expression so that the template definition is parsed correctly:
We can do this by adding a layer of indirection:
namespace detail {
template <class T, class Func1Arg>
struct func1_t {
using type = decltype(std::declval<T>().template func1<Func1Arg>());
};
};
Then you use this trait as the trailing return type:
template<typename T1>
auto func1() -> typename detail::func1_t<dclas,T1>::type
{
return(static_cast<dclas*>(this)->template func1<T1>());
}
I want to try to do a generic getter by using C++11, but I have an issue if I try to define the generic getter outside the template class.
This code works fine
template <typename T>
class test
{
public:
........
//generic getter
template <typename F>
auto getter_elem_member(F fun)->decltype(fun())
{ return elem.fun(); }
private
T elem;
};
but if I try the code in this way:
template <typename T>
class test
{
public:
........
//generic getter
template <typename F>
auto getter_elem_member(F fun)->decltype(fun());
private
T elem;
};
template <typename T>
template <typename F>
auto test<T>::getter_elem_member(F fun)->decltype(fun())
{ return elem.fun(); }
I obtain the error "Member declaration not found".
Where am I wrong?
Thanks in advance for any suggestions
I am doing exercises with new features, here a example that works (unless a warning)
#include <iostream>
#include <string>
template <typename T>
class test
{
public:
//costruttori - distruttori
test(){}
~test(){}
public:
//generic getter
template <typename F>
auto getter_elem_member(F fun)
{ return (elem.*fun)(); }
//generic getter
template <typename F>
auto getter_elem_member2(F fun)->decltype(fun())
{ return fun(); }
private:
T elem;
};
struct A
{
std::string print(){return "ciao";}
static std::string print2(){return "ciao";}
};
int main()
{
test<A> test1;
std::cout << test1.getter_elem_member(&A::print) << std::endl;
std::cout << test1.getter_elem_member2(A::print2) << std::endl;
}
If you're trying to make a proxy function which calls a member function of a private member variable through a member function pointer, I don't think you need decltype at all.
// Member function pointer version
template <class Ret>
Ret getter_elem_member(Ret (T::*fun)())
{ return (elem.*fun)(); }
// Generic function object version
template <class F>
auto getter_elem_member(F fun) -> decltype(fun())
{ return fun(); }
If a function pointer is given, the first one will be called. For other callable types, the second one will be called.
The second one, which is for a generic callable object, seems unnecessary. Since you can't access the private member in fun anyway, so it's better calling fun() outside than passing it and making your class call it.
It appears that you're trying to use a template function-like paradigm.
You should use std::function to do this. If not, you can probably get along with some sort of templated function pointer to do this.
I am wondering if c++11/c++14 would/already support something like vector<auto>?
If not, Is there any reason?
It's not supported directly, and not immediately clear exactly what you want it to do.
Comments have already mentioned a couple of possibilities (such as Boost any and variant classes) for creating heterogeneous collections. I hope this isn't what you were after, because heterogeneous collections fit poorly with C++ so using them is ugly and clumsy. I suppose there are cases/situations where these really would be the best choices available, but at least in my experience, those cases are fairly rare.
Another possible interpretation of what you might want would be a vector that (like auto in general) holds exactly one type, but that type is deduced from the initializer, so if you initialized the vector from some ints, you'd get a vector<int>, and if you initialized it from some strings, you'd get a vector<string>, and so on. Although the language doesn't support that directly, it is pretty easy to simulate it to at least some degree. Template classes can't/don't ever deduce template parameters, but template functions do/can. Therefore, we can create a tiny function template to take some initializers, deduce their type, and return a vector of that type. For example:
template <class T>
std::vector<T> make_vector(std::initializer_list<T> init) {
return std::vector<T>(init);
}
This returns a vector<T> (with T deduced from the type of data in the initializer list), so you can do things like:
auto a = make_vector({ 1, 2, 3, 4 }); // a -> vector<int>
auto b = make_vector({ 1.0, 2.0, 3.0 }); // b -> vector<double>
auto c = make_vector({ "1"s, "2"s, "3"s }); // c -> vector<std::string>
That last one requires a user-defined literal operator that's new in C++14 (which many compilers don't yet support). The rest should be fine with C++11.
There has also been some discussion (and a proposal in N3602) of adding a capability (perhaps to C++17) where you'd be able to define something like the make_vector above, but as something like a templated constructor for the class. This would let you use argument deduction on the constructor to deduce the template parameter for the class as a whole, so you'd be able to do something like:
X x(1); // deduces as X<int>
X x(2.0) // deduces as X<double>
Warning though: this has been proposed but not accepted. It may (easily) never be accepted--and even if it is, it may be altered significantly before that happens.
No, not in C++11 or C++14, which are already finished and published.
But it's possible that vector<auto> and similar things like tuple<auto...> will be in C++17 as part of the Concepts work.
It follows quite naturally from the fact that std::vector<T> can be used in function templates and class template partial specializations where T is a template parameter, and also from the fact that polymorphic lambdas allow auto as a function parameter type (which is shorthand for a function template with deduced parameters).
The Concepts TS allows a "generic function" to be declared like:
auto func(auto arg);
Since you can have a function template like this:
template<typename T>
auto func(std::vector<T> v);
it makes sense to extend the generic function syntax to allow:
auto func(std::vector<auto> v);
and once you allow that in a function declaration, it should also be possible to allow it in variable declarations:
std::vector<auto> v = function_returning_vector_of_something();
The reason it isn't in C++11 is that auto was new, and it would have been too ambitious to try and make it do too much. In C++14 polymorphic lambdas were new, and again, expanding the uses of auto any further would have been ambitious.
For C++17 we have more experience with using auto in real code, and compiler writers are familiar with implementing it and know what is possible without too much effort.
A boost::any can store an instance of any type that can be copied, which is a lot of types.
In order to get the data out of your any, you have to know the exact type you stored in it.
Writing a simple any isn't hard:
#include <memory>
#include <utility>
struct any_internal {
virtual any_internal* clone() const = 0;
virtual ~any_internal() {};
};
template<class T>
struct any_details;
class any {
std::unique_ptr<any_internal> internal;
public:
any() = default;
any( any && ) = default;
any( any const&& o):any(o) {}
any( any & o ):any( const_cast<any const&>(o) ) {}
any& operator=( any && ) = default;
any& operator=( any const&& o ) { return this->operator=( o ); };
any& operator=( any & o ) { return this->operator=( const_cast<any const&>(o) ); };
any( any const& o ):internal( o.internal?o.internal->clone():nullptr ) {}
any& operator=( any const& o ) {
any tmp(o);
using std::swap;
swap( internal, tmp.internal );
return *this;
}
template<class U>
void reset( U&& o );
template<class U, class... Args>
void emplace( Args&&... args );
template<class U>
any( U&& o );
template<class U>
any& operator=(U&& o);
template<class T> T* get();
template<class T> T const* get() const;
template<class T> T* fast_get();
template<class T> T const* fast_get() const;
explicit operator bool() const { return internal!=nullptr; }
};
template<class T>
struct any_details : any_internal {
T t;
template<class...Args>
any_details( Args&&... args ):t(std::forward<Args>(args)...) {}
any_internal* clone() const override { return new any_details<T>{t}; }
};
template<class U, class... Args>
void any::emplace( Args&&... args ) {
internal.reset( new any_details<U>( std::forward<Args>(args)... ) );
}
template<class U>
void any::reset( U&& o ) {
emplace<typename std::decay<U>::type>( std::forward<U>(o) );
}
template<class U>
any::any( U&& o ) {
reset( std::forward<U>(o) );
}
template<class U>
any& any::operator=(U&& o) {
reset( std::forward<U>(o) );
return *this;
}
template<class T> T* any::get() {
auto* r = dynamic_cast< any_details<T>* >( internal.get() );
if (r) return &r->t;
return nullptr;
}
template<class T> T const* any::get() const {
auto* r = dynamic_cast< any_details<T>* >( internal.get() );
if (r) return &r->t;
return nullptr;
}
template<class T> T* any::fast_get() {
auto* r = static_cast< any_details<T>* >( internal.get() );
if (r) return &r->t;
return nullptr;
}
template<class T> T const* any::fast_get() const {
auto* r = static_cast< any_details<T>* >( internal.get() );
if (r) return &r->t;
return nullptr;
}
and a std::vector<any> behaves much like you might want a std::vector<auto> to do.
Increased efficiency can be achieved via small buffer optimizations (ie, store the T within the any if the t is small, instead of using the heap).
You'd probably also want to split get from fast_get, where get does a dynamic_cast and fast_get does a static_cast, again for efficiency. (When you know for certain, you can fast_get)
Basically this is a gussied up void*.