Is it possible to implement std::optional such that sizeof(std::optional<double>) == 8 by somehow using that you can store characters in a NAN, see http://en.cppreference.com/w/cpp/numeric/math/nan? Are there implementations that do that? Can it be done in terms of the functionality that is available in the standard?
I don't think this can be done because there is no rule preventing programs from utilizing and relying on the extra bits in NaN on their own. Then if you store the magic number into the optional it looks like it's not present instead of the application's special NaN.
Answer is multifold.
First of all, it can not be implemented with the functionality available in Standard, since Standard says nothing of floating point implementation.
Second, for IEEE 754 floating points you can implement your own optional by specializing std::optional for doubles. However, this would mean that you exclude a valid value (NaN is a result produced by some arithmetic operations) from your range of values. However, diving deep into IEEE 754, you might choose a specific NaN representation (there are a lot of those!) as a no-value.
It is not possible to implement std::optional like that because it contradicts the post-conditions that specify how the class (template) behaves. For example: std::optional contains a value if it is initialized with a value of type T, but your suggested std::optional<double> would not contain a value if it was initialized with a value that is the special NaN value that you've chosen.
Also, the C++ standard does not guarantee/require that the floating point type supports (quiet) NaN. Some systems do not.
It is certainly possible to implement your own non-standard optional class with different semantics. Of course, you will then be relying on the implementation defined fact that NaN values exist. You also have to rely on the knowledge of the floating point representation, because as far as I know, there are no standard utilites for inspecting the NaN payload - only for generating a value that has a specific payload.
Implementing what you propose is rather trivial, using a good text editor and cut-and-paste. Since it's a good idea, I've decided to add it to my tool box. My main motivation is that std::optional<>s are rather big, and thus not practical to use in std::variant<> types.
#include <type_traits>
#include <limits>
#include <exception>
class bad_optional_flt_access
: public std::exception
{
public:
bad_optional_flt_access() {}
const char* what() const noexcept override
{
return "bad optional float access";
}
};
template <typename Float, bool = std::is_floating_point<Float>::value>
class optional_flt;
template <typename Float>
class optional_flt<Float, false> {};
template <typename Float>
class optional_flt<Float, true>
{
public:
constexpr optional_flt() noexcept : value_(std::numeric_limits<Float>::quiet_NAN()) {}
constexpr optional_flt(const Float& val) noexcept : value_(val) {}
template<typename T>
constexpr optional_flt(const T& val) noexcept : value_(Float(val)) {}
constexpr bool has_value() const noexcept
{
return value_ != std::numeric_limits<Float>::quiet_NAN();
}
void reset() noexcept { value_ = std::numeric_limits<Float>::quiet_NAN(); }
constexpr void swap(optional_flt& other) noexcept { std::swap(value_, other.value_); }
constexpr operator bool() const noexcept { return has_value(); }
Float& value () &
{
if (!has_value())
throw bad_optional_flt_access();
return value_;
}
Float&& value () &&
{
if (!has_value())
throw bad_optional_flt_access();
return value_;
}
constexpr const Float& value () const &
{
if (!has_value())
throw bad_optional_flt_access();
return value_;
}
Float& operator * () & noexcept { return value_; }
constexpr const Float& operator * () const & noexcept{ return value_; }
template< class U >
constexpr Float value_or( U&& default_value ) const&
{
return (has_value()) ? value_ : default_value;
}
template< class U >
constexpr Float value_or( U&& default_value ) &&
{
return (has_value()) ? value_ : default_value;
}
private:
Float value_;
};
template< class T, class U >
constexpr bool operator==( const optional_flt<T>& lhs, const optional_flt<U>& rhs )
{
return lhs.value() == rhs.value();
}
template< class T, class U >
constexpr bool operator!=( const optional_flt<T>& lhs, const optional_flt<U>& rhs )
{
return lhs.value() != rhs.value();
}
template< class T, class U >
constexpr bool operator<( const optional_flt<T>& lhs, const optional_flt<U>& rhs )
{
return lhs.value() < rhs.value();
}
template< class T, class U >
constexpr bool operator<=( const optional_flt<T>& lhs, const optional_flt<U>& rhs )
{
return lhs.value() <= rhs.value();
}
template< class T, class U >
constexpr bool operator>( const optional_flt<T>& lhs, const optional_flt<U>& rhs )
{
return lhs.value() > rhs.value();
}
template< class T, class U >
constexpr bool operator>=( const optional_flt<T>& lhs, const optional_flt<U>& rhs )
{
return lhs.value() >= rhs.value();
}
template<typename T>
constexpr optional_flt<T> make_optional_flt(const T& x)
{
return optional_flt<T>(x);
}
int main()
{
int i = 2;
auto x = optional_flt<float>{i};
auto y = optional_flt<double>(2.5);
return (*x < .5) ? sizeof(optional_flt<double>) : 1;
}
The code above is gcc -std=c++11, clang -std=c++14, and cl /std:c++11 compatible.
Related
How can I make it so that (with objects of different template types) A*B and B*A give the same result, where the type of the result is determined according to the usual C++ type promotion rules?
For example:
int main()
{
number<float> A(2.0f);
number<double> B(3.0);
A*B; // I want 6.0 (double)
B*A; // I want 6.0 (double)
return 0;
}
At the moment, I can only multiply objects of the same template type. For example, something like this:
template<typename T>
class number
{
public:
number(T v) : _value(v) {}
T get_value() const { return _value; }
number& operator*=(const number& rhs)
{
_value *= rhs.get_value();
return *this;
}
private:
T _value;
};
template<typename T>
inline number<T> operator*(number<T> lhs, const number<T>& rhs)
{
lhs *= rhs;
return lhs;
}
EDIT: Or, as in the answers, I can multiply objects of different template types, but always returning the same type as lhs. Is there any way to instead return an object whose type is determined by the standard type promotion rules?
EDIT 2: I would like to avoid C++11 features if possible.
You have to templatize e.g. the rhsparameters:
template<typename T>
class number
{
public:
number(T v) : _value(v) {}
T get_value() const { return _value; }
template<class E>
number& operator*=(const number<E>& rhs)
{
_value *= rhs.get_value();
return *this;
}
private:
T _value;
};
template<class T, class E, class RET = decltype(T()*E())>
number<RET> operator*(number<T>& lhs, const number<E>& rhs)
{
return lhs.get_value()*rhs.get_value();
}
You can use std::common_type<> to obtain the type required for the return. For example
template<typename X>
struct number
{
// ...
template<typename Y>
number(number<Y> const&other); // needed in line 1 below
template<typename Y>
number&operator=(number<Y> const&other); // you may also want this
template<typename Y>
number&operator*=(number<Y> const&other); // needed in line 2 below
template<typename Y>
number<typename std::common_type<X,Y>::type> operator*(number<Y> const&y) const
{
number<typename std::common_type<X,Y>::type> result=x; // 1
return result*=y; // 2
}
};
I left out the implementations of the templated constructor and operator*=.
Unfortunately, std::common_type is C++11, which you want to avoid for obscure reasons. If you only work with built-in types (double, float, int, etc), you can easily implement your own version of common_type. However, if you want to do sophisticated meta-template programming, it is strongly recommended to move on to C++11 – it's already 4 years old and mostly backwards compatible.
You need a templated overload for the operator*()
template<typename T>
class number {
public:
// ...
template<typename U>
number& operator*=(const number<U>& rhs) {
// ...
}
// ...
};
And the same for the binary operator
template<typename T,typename U>
inline number<T> operator*(number<T> lhs, const number<U>& rhs) {
lhs *= rhs;
return lhs;
}
I am in the process of converting a large set of geospatial code from one projection to another. To enforce proper units during this conversion, I have introduced Distance, Point, Rectangle, and Polygon templates which take a tag indicating what coordinate system is used. This is working out fairly well, but there are a lot of places where checks are performed for non-zero (!= 0) or positive values (> 0). I would like to be able to overload these operators to allow comparing against 0 without comparing against any other number. Is it possible to accomplish this?
As an additional restriction, I cannot use constexpr because I must support VS 2013, but I'd still be interested to hear if there is a way to do this with constexpr
Just for reference, I am working with something like this:
template<typename Tag> struct Distance
{
int value;
};
template<typename Tag> struct Point
{
Distance<Tag> x;
Distance<Tag> y;
};
// This works fine for comparing two Distances
template<typename Tag> bool operator>(const Distance<Tag>& a, const Distance<Tag>& b) {return a.value > b.value;}
// But I don't want this to allow a > 14, only a > 0
template<typename Tag> bool operator>(const Distance<Tag>& a, int b) {return a.value > b;}
struct Mercator;
typedef Point<Mercator> MercPoint;
struct GuiScale;
typedef Point<GuiScale> GuiPoint;
// etc.
You may use nullptr_t as a hack (as literal 0 convert to nullptr):
template<typename Tag> bool operator>(const Distance<Tag>& a, std::nullptr_t b) {return a.value > 0;}
You might use the conversion-to-any-pointer of a literal zero:
#include <type_traits>
template<typename Tag>
struct Distance
{
private:
using literal_zero = void(Distance::*)();
template<typename U>
using enable_nullptr = typename std::enable_if<
std::is_same< typename std::decay< U >::type, std::nullptr_t >::value
>::type;
public:
int value;
bool operator<( literal_zero ) const { return value < 0; }
template<typename U>
enable_nullptr<U> operator<( const U& ) const = delete;
};
int main() {
Distance<int> a;
a.value = 0;
a < 0;
// a < 42; // does not compile
// a < nullptr; // does not compile
}
This, unlike the other answer, also disallows a < nullptr. Also, if you remove the nullptr-related part and replace the using literal_zero = ... with a typedef, the same technique works with C++98.
Live example
If it's semantically valid to compare with a literal 0, it's valid to allow a conversion from literal 0 as well. With the conversion in place, you need no special case comparisons (Live at Coliru):
template<typename Tag> struct Distance
{
int value;
Distance() = default;
explicit constexpr Distance(int v) : value(v) {}
constexpr Distance(std::nullptr_t) : value(0) {}
friend constexpr bool operator == (const Distance& lhs, const Distance& rhs) {
return lhs.value == rhs.value;
}
friend constexpr bool operator < (const Distance& lhs, const Distance& rhs) {
return lhs.value < rhs.value;
}
// ...
};
Supose I need to write a class which acts as a wrapper for values:
template<typename T>
struct value_wrapper
{
T value;
value_wrapper( const T& v ) : value( v ) {}
//etc...
};
The class is dessigned to be used as an alias of the original value, so if that value was an rvalue, the wrapper holds the value, and if it was an lvalue the wrapper holds a reference to it.
The class is supposed to overload, say, comparison operators and be used in this way:
template<typename T , typename U>
bool f( const T& lhs , const T& rhs )
{
return wrapper( lhs ) == wrapper( rhs );
}
Or this:
int main()
{
int a , b;
bool flag = wrapper( a ) == wrapper( b ) || wrapper( a ) == wrapper( 2 );
}
My question is: Whats the best (efficient) way to implement such thing?
That questions seems to broad, I mean:
How I define the member value? As T& for lvalues, and T for rvalues?
Is there any standard way to write this kind of universal (rvalue and lvalue) alias?
I would simply provide suitable conversion operators:
#include <utility>
#include <type_traits>
template <typename T> struct Wrapper
{
static_assert(!std::is_reference<T>::value, "Do not use a reference type");
using type = T;
T value;
Wrapper(T && t) : value(std::move(t)) {}
Wrapper(T const & t) : value(t) {}
operator T const & () const noexcept { return value; }
operator T & () & noexcept { return value; }
operator T && () && noexcept { return std::move(value); }
// maybe some more CV variants...
};
template <typename U> struct Wrapper<U &>
{
using type = U &;
U & ref;
Wrapper(U & u) : ref(u) {}
operator U & () { return ref; }
};
I'd accompany this with a deducing function:
template <typename T> Wrapper<T> wrap(T && t)
{ return Wrapper<T>(std::forward<T>(t)); }
Example usage:
int n = 10;
bool b = wrap(n) == wrap(5 + 5)
The conversion operators allow you to use whatever operators are defined on the underlying type.
I think Kerrek SB is on the right track by providing a specialization (got my +1 a long time ago), so each case is handled most efficiently.
The problem is you can't just add implicit conversion operators and if you want to provide your own operator overloads, things can become quite tricky.
The solution I came up with tries to deal with this by putting the information which case a certain variable is into a boolean template parameter. Here's the basic framework for the value_wrapper class:
template< typename T, bool >
class value_wrapper
{
private:
T t_; // store a value
public:
explicit value_wrapper( T&& t ) : t_( std::move( t ) ) {}
const T& cref() const { return t_; }
};
template< typename T >
struct value_wrapper< T, true > // specialization for lvalue references
{
private:
const T& t_; // store a reference
public:
explicit value_wrapper( const T& t ) : t_( t ) {}
const T& cref() const { return t_; }
};
The tricky part is the convenience method to wrap the values:
// needs a better name and needs to be moved into a "detail" or "impl" namespace
template< typename T >
using helper = value_wrapper< typename std::decay< T >::type,
std::is_lvalue_reference< T >::value >;
template< typename T >
helper< T > wrap( T&& t )
{
return helper< T >( std::forward< T >( t ) );
}
That way value_wrapper's first template parameter is always the decayed type, which makes everything easier now:
template< typename T, bool BL, bool BR >
bool operator==( const value_wrapper< T, BL >& lhs, const value_wrapper< T, BR >& rhs )
{
return lhs.cref() == rhs.cref();
}
(obviously you want to implement them differently, but you can always access the stored values via cref() in a uniform way)
Live example
You might need to adjust this if you need non-constant access, etc. but I hope the above gets you started. If you need more help/ideas, feel free to ask :)
To narrow it down: I'm currently using Boost.Unordered. I see two possible solutions:
Define my own Equality Predicates and Hash Functions and to utilize templates (maybe is_pointer) to distinct between pointers and instances;
Simply to extend boost::hash by providing hash_value(Type* const& x) as for hashing; and add == operator overload as free function with (Type* const& x, Type* const& y) parameters as for equality checking.
I'm not sure whether both variations are actually possible, since I didn't test them. I would like to find out you handle this problem. Implementations are welcome :)
EDIT 1:
What about this?
template<class T>
struct Equals: std::binary_function<T, T, bool> {
bool operator()(T const& left, T const& right) const {
return left == right;
}
};
template<class T>
struct Equals<T*> : std::binary_function<T*, T*, bool> {
bool operator()(T* const& left, T* const& right) const {
return *left == *right;
}
};
EDIT 2:
I've just defined:
friend std::size_t hash_value(Base const& base) {
boost::hash<std::string> hash;
return hash(base.string_);
}
friend std::size_t hash_value(Base* const& base) {
return hash_value(*base);
}
And then:
Derived d1("x");
Derived d2("x");
unordered_set<Base*> set;
set.insert(&d1);
assert(set.find(&d2) == end());
Debugger says that friend std::size_t hash_value(Base* const& base) is never called (GCC 4.7). Why is that?
EDIT 3:
I found out that template <class T> std::size_t hash_value(T* const& v) in boost/functional/hash.hpp on line #215 (Boost 1.49) is Boost's specialization for pointers and it simply masks your custom implementation of hash_value such as mine in EDIT 2.
Therefore, it seems like the only way here is to create a custom Hash Functor.
For the hash function, you have a choice between specializing boost::hash (or std::hash in the newer standard) or defining a new functor class. These alternatives work equally well.
For the equality operator, you need to define a new functor, because you cannot redefine the equality operator over pointers. It's a built-in operator (defined in functional terms as bool operator==( T const *x, T const *y )) and cannot be replaced.
Both of these can be defined generically by using a templated operator() in a non-templated class.
struct indirect_equal {
template< typename X, typename Y >
bool operator() ( X const &lhs, Y const &rhs )
{ return * lhs == * rhs; }
};
Follow a similar pattern for the hasher.
Taking into consideration all edits in the original post I would like to provide complete solution which satisfies my needs:
1. Equality:
template<class T>
struct Equal: ::std::binary_function<T, T, bool> {
bool operator()(T const& left, T const& right) const {
::std::equal_to<T> equal;
return equal(left, right);
}
};
template<class T>
struct Equal<T*> : ::std::binary_function<T*, T*, bool> {
bool operator()(T* const & left, T* const & right) const {
Equal<T> equal;
return equal(*left, *right);
}
};
2. Hashing:
template<class T>
struct Hash: ::std::unary_function<T, ::std::size_t> {
::std::size_t operator()(T const & value) const {
::boost::hash<T> hash;
return hash(value);
}
};
template<class T>
struct Hash<T*> : ::std::unary_function<T*, ::std::size_t> {
::std::size_t operator()(T* const & value) const {
Hash<T> hash;
return hash(*value);
}
};
So now I can continue using Boost's hash_value and it will not get masked for pointer types by Boost's default implementation (see EDIT 3).
3. Example:
In my application I have a thin wrapper for unordered_set which now looks like that:
template<class T, class H = Hash<T>, class E = Equal<T> >
class Set {
public:
// code omitted...
bool contains(const T& element) const {
return s_.find(element) != end();
}
bool insert(const T& element) {
return s_.insert(element).second;
}
// code omitted...
private:
::boost::unordered::unordered_set<T, H, E> s_;
};
So if we have some base class:
class Base {
public:
Base(const ::std::string& string) {
if (string.empty())
throw ::std::invalid_argument("String is empty.");
string_ = string;
}
virtual ~Base() {
}
friend bool operator==(const Base& right, const Base& left) {
return typeid(right) == typeid(left) && right.string_ == left.string_;
}
friend bool operator!=(const Base& right, const Base& left) {
return !(right == left);
}
friend ::std::size_t hash_value(Base const& base) {
::boost::hash<std::string> hash;
return hash(base.string_);
}
friend ::std::size_t hash_value(Base* const& base) {
return hash_value(*base);
}
private:
::std::string string_;
};
And some derived class:
class Derived: public Base {
public:
Derived(const ::std::string& string) :
Base(string) {
}
virtual ~Derived() {
}
};
Then we can even use polymorphism (which was my primary intention BTW):
Derived d1("¯\_(ツ)_/¯");
Derived d2("¯\_(ツ)_/¯");
Set<Base*> set;
set.insert(&d1);
assert(set.contains(&d2));
Hope this helps. Any suggestions are welcome.
I got this n-dimensional point object:
template <class T, unsigned int dimension> class Obj {
protected:
T coords[dimension];
static const unsigned int size = dimension;
public:
Obj() { };
Obj(T def) { for (unsigned int i = 0; i < size; ++i) coords[i]=def; };
Obj(const Obj& o) { for (unsigned int i = 0; i < size; ++i) coords[i] = o.coords[i]; }
const Obj& operator= (const Obj& rhs) { if (this != &rhs) for (unsigned int i = 0; i < size; ++i) coords[i] = rhs.coords[i]; return *this; }
virtual ~Obj() { };
T get (unsigned int id) { if (id >= size) throw std::out_of_range("out of range"); return coords[id]; }
void set (unsigned int id, T t) { if (id >= size) throw std::out_of_range("out of range"); coords[id] = t; }
};
and a 3D point class which uses Obj as base class:
template <class U> class Point3DBase : public Obj<U,3> {
typedef U type;
public:
U &x, &y, &z;
public:
Point3DBase() : x(Obj<U,3>::coords[0]), y(Obj<U,3>::coords[1]), z(Obj<U,3>::coords[2]) { };
Point3DBase(U def) : Obj<U,3>(def), x(Obj<U,3>::coords[0]), y(Obj<U,3>::coords[1]), z(Obj<U,3>::coords[2]) { };
Point3DBase(U x_, U y_, U z_) : x(Obj<U,3>::coords[0]), y(Obj<U,3>::coords[1]), z(Obj<U,3>::coords[2]) { x = x_; y = y_; z= z_; };
Point3DBase(const Point3DBase& other) : x(Obj<U,3>::coords[0]), y(Obj<U,3>::coords[1]), z(Obj<U,3>::coords[2]) { x = other.x; y = other.y; z = other.z; }
// several operators ...
};
The operators, basically the ones for comparison, use the simple compare-the-member-object approach like:
friend bool operator== (const Point3DBase<U> &lhs, const Point3DBase<U> rhs) { return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z); }
Then it occured to me that for the comparion of double values the simply equality approach is not very useful since double values should be compared with an error margin. What would be the best approach to introduce an error margin into the point? I thought about an epsDouble type as template parameter but I can't figure out how to achieve this.
edit:
I've seen chained output stream operators that call the output stream operator of the type of the output stream operator ... Is there a way to delegate the comparison to a custom type that represents a float point type?
If you want one epsilon value for all instances of a given floating type, it's actually quite simple:
template <>
bool operator<(const Point3DBase<double>& lhs, const Point3DBase<double>& rhs)
{
}
If not, then I shall orient you toward Policy-based Design as Alexandrescu showed:
namespace detail
{
template <class U>
struct DefaultComparator: std::binary_function<bool, U, U>
{
bool operator()(U lhs, U rhs) const { return lhs < rhs; }
};
}
template < class U, class Comparator = detail::DefaultComparator<U> >
class Point3DBase;
template < class U, class C>
bool operator<(Point3DBase<U,C> const& lhs, Point3DBase<U,C> const& rhs)
{
return C()(lhs,rhs);
}
Note that you can still define a safe default by specializing DefaultComparator
namespace detail
{
template <>
struct DefaultComparator<float> {};
template <>
struct DefaultComparator<double> {};
}
With this definition, it is not possible to use operator== without passing a Comparator parameter oneself. Another solution would be to allow it but provide a default epsilon in the definition of the two specialization above.
All other operations (>, <=, >=, ==, !=) can be trivially derived (though perhaps not efficiently) from <, for example by deriving from boost::equality_comparable and/or boost::less_than_comparable.
Yeah, you can't have a template parameter of a floating point type. You could have an int parameter instead, telling the negative 10 base log of the epsilon value, e.g. a value of 3 would mean 0.001 .
If you want to master the epsilon you can define a wrapper class of double that takes care of the this epsilon when comparing instances of this class. In this way you are able to use whatever other functions or classes that are templated on the numeric type.
template <int EPS>
class DoubleEps {
double val;
public:
operator double {return val;}
DoubleEps(double d) : val(d) {}
operator==(DoubleEps d) {
// take care of epsilon
}
// other operators if needed
};