Friend name resolving scope in C++ - c++

This is legacy code that likely worked in era 3.2 or 2.8 g++, but no longer. It does still compile under microsoft C/C++ optimizing compiler v.17. The code has also been trimmed down from the original to isolate the salient issue.
in function +=, error: 'to_every' was not declared in this scope
class Matrix {};
class ElementWiseConst
{
public:
ElementWiseConst(const Matrix& m){}
};
class ElementWise : public ElementWiseConst
{
public:
ElementWise(const ElementWise&);
ElementWise(Matrix& m) : ElementWiseConst(m) {}
void operator += (const double val);
friend ElementWise to_every(Matrix& m) { return m; }
};
Matrix& operator += (Matrix& m, const double val) {
to_every(m) += val;
return m;
}
Is this an implicit conversion or scoping that microsoft is incorrectly allowing?

to_every is defined inside of ElementWise and thus can only be found via ADL. The compiler will look at the arguments provided and use its associated namespaces and classes to find the name to_every. The associate classes of Matrix is Matrix itself and its associated namespace is the global namespace (assuming it was declared there). ElementWise needs to be an associated class, thus to_every cannot be found.
To get this to work you can:
Define to_every outside of the class.
Make ElementWise an associated class by making it a template argument (#sehe):
template<class T>
class ADLMatrix {};
using Matrix = ADLMatrix<class ElementWise>;

Related

C++ How to initialize const share_ptr<const obj> in constructor? [duplicate]

I understand that for a class
class A {
const int myint;
public:
A (const int yourint);
A (const std::string yourstring);
};
I could initialize myint in the initializer list like so:
A::A (const int yourint) : myint (yourint) {};
However, what is the proper way of initializing myint from the second constructor if the the data required to compute it comes say from a string and the computations may be involved?
Use a function call inside a delegating (if avaliable, not neccessarily) constructor's member initialization list:
A::A(std::string const& yourstring) : A(compute_myint(yourstring)) {};
Pass std::string by const&, not just const, while you're at it.
compute_myint can be non-member, static member, possibly not accessible from outside the class, whichever makes the most sense.
Here you would want to use delegating constructors, if you can, or you could compute in the ctor. See my second example for the second option. An example for your class would be:
Option 1: Delegating Constructors: C++11 forward
class A {
const int myint;
static int parse_int(const std::string& string) {/*...*/}
public:
A (const int yourint) : myint{yourint};
A (const std::string yourstring) : A{parse_int(yourstring)};
}
By the way, since parse_int only computes integers, then it could be static, meaning it does not require a class instance to be used. Of course, there is no requirement, as the function could be a member just as well, (non static), although static is safer, since it will almost always guarantee the construction of the object.
Option 2: Constructor Computation, non delegating
This method could be used in any C++ version.
class A {
const int myint;
static int parse_int(const std::string& string) {/*...*/}
public:
A (const int yourint) : myint(yourint);
A (const std::string yourstring) : my_int(parse_int(yourstring));
}
Just use a member function.
Keep in mind that it's safer (i.e. less error-prone) to use a static member function for things like this than a non-static one, because the class isn't fully initialized yet when the function is called.
class A {
const int myint;
public:
A(const int x) : myint(x) {}
A(std::string const& s) : myint(compute(s)) {}
private:
static int compute(std::string const& s) { return (int)s.length(); }
};
I've been annoyed by this issue quite a few times, so I have developed a small utility to solve it in the general case. The full code is as follows:
namespace initBlock_detail {
struct tag { };
template <class F>
decltype(auto) operator + (tag, F &&f) {
return std::forward<F>(f)();
}
}
#define initBlock \
initBlock_detail::tag{} + [&]() -> decltype(auto)
And it is used as follows:
int const i = initBlock {
// Any complex calculation
// and then return the value
return foo;
};
See it live on Coliru
The structure is similar to Andrei Alexandrescu's ScopeGuard implementation, which uses an infix operator overload and a lambda to achieve that light syntax. i's type can be deduced, can be a reference, etc. Other useful features include the possibility to place using namespace declarations inside the init-block. Any movable and/or copyable type can be used.

Compilation error about operator reloading using boost::variant

I'am trying to learn boost.variant. However, the code which I copied from a book won't pass the compilation:
class var_print : public boost::static_visitor<void>
{
public:
template<typename T>
void operator()(T &i) {
i *= 2;
cout<<i<<endl;
}
};
Here is how I tried to use it.
typedef boost::variant<int,double,string> var_t;
var_t v(1); //v->int
boost::apply_visitor(var_print(),v);
The compiler generates the following error:
ERROR:no match for 'operator*=' in 'i *= 2'
That puzzles me,since template function will determine the type of parameter whenever it's called and int should defined the operator *=.
You need to have a separate operator() for std::string& since no operator *= is defined for std::string.
In addition, your operator must be marked const since you are passing a temporar visitor instance to apply_visitor.

Overload math operators [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why is my log in the std namespace?
Based on Overload a C++ function according to the return value, I did the following experiment:
#include <cmath>
class myType
{
private:
double value;
myType(double value) : value(value) {}
public:
myType& operator= (const myType& other) {
if (this != &other) value = other.value;
return *this;
}
static myType test(double val) { return myType(val); }
friend std::ostream& operator<<(std::ostream& target, const myType& A);
};
std::ostream& operator<<(std::ostream& target, const myType& A){
target << A.value;
return target;
}
class asin {
private:
double value;
public:
asin(double value)
: value(std::asin( (value<-1.0) ? -1.0 : (value>1.0?1.0:value) ))
{}
operator double() { return value; }
operator myType() { return myType::test(value); }
};
int main(int argc, char *argv[])
{
myType d = asin(1.0);
std::cout << d << std::endl;
return 0;
}
which resulted in
error: ‘myType::myType(double)’ is private
on the first line in main(). A bit more experimenting showed me that this works fine and as expected when I change the classname asin to Asin (or anything else for that matter). So apparently, I'm not allowed to call my class asin, while the act of defining it (and not using it) does not give me any warning/error.
Now I know all of this is bad practice, so don't flame me for that. I ask this purely out of academic interest: why can't I call my class asin, or acos or atan or anything like that? I was under the impression that cmath hid everything in the std-namespace, so that defining this class in the global namespace would not give rise this particular problem.
Can anyone explain what's going on?
asin is a defined as global function in c++ standard library, and also defined in math library, (so you even dont have to use std::)
If you try using unamed namespace then you would get 'use of `asin' is ambiguous' error.
And named namespace solves your issue.
For some IDEs, for example Visual Studio, you do not even need to include cmath. It has these functions already defined in the global namespace. Try to exclude cmath and you will see that asin() is still defined.

Friend operator declaration in a template class

I have a nice problem with a friend operator declared in a template class and an explicit instantiation of the class like this:
template<class T>
class IneqCmp{
friend bool operator!=(T a, T b){
return !(a==b);
}
};
struct IntCont{
int x;
bool operator==(IntCont that) const{
return x==that.x;
}
};
template class IneqCmp<IntCont>;
int main(){
IntCont a{1}, b{2};
while(a!=b);
}
I think operator!=(IntCont, IntCont) should be instantiated at the point of instantiation of IneqCmp<IntCont> but it isn't. Why?
The problem with the code above is not whether operator!= is or not defined, but the fact that it will never be found by lookup*.
When you declare a function as a friend of a class the declaration is strange in the sense that it declares a namespace level function, but the declaration of it will only be available through ADL on the enclosing type. Because your operator!= does not take IneqComp as any of the two arguments, it is effectively impossible to find through lookup.
If what you want to do is providing a default implementation of the operator!= that will be available to a set of types, you can tackle the problem in different ways.
First, you can add IneqCmp to the ADL set by using inheritance:
struct IntCont : IneqCmp<IntCont> {
// ...
};
Because ADL looks in the class of the argument, and also in the base classes, this will effectively trigger lookup inside IneqCmp<IntCont> and that will find the friend declaration and thus the free function.
Another alternative would be to add a namespace where the generic operator!= will be defined (so that it won't be found otherwise) and a tag type. Then inherit from that tag:
namespace inequality_comparable {
struct tag {};
template <typename T>
bool operator!=( T const & a, T const & b ) {
return !(a==b);
}
}
struct IntCont : inequality_comparable::tag {
};
bool operator==( IntCont const & a, IntCont const & b ) {
return ...;
}
int main() {
IntCont a,b;
std::cout << a != b << "\n";
}
The trick here is that because inequality_comparable::tag is a base of your type, it will add the namespace inequality_comparable to lookup. When the compiler encounters a != b in main it will try to use an operator!= defined in the current scope, the class IntCont and it's bases and the namespace where IntCont and its bases are defined.
* If you want to verify that the operator has actually be generated, try to add it:
bool operator!=(IntCont a, IntCont b){
return !(a==b);
}
If the operator has been defined because of the instantiation of IneqCmp then that will trigger a compiler error. Alternatively, you can just compile and inspect the generated object file for the symbol.

Idiomatic use of std::rel_ops

What is the preferred method of using std::rel_ops to add the full set of relational operators to a class?
This documentation suggests a using namespace std::rel_ops, but this seems to be deeply flawed, as it would mean that including the header for the class implemented in this way would also add full relational operators to all other classes with a defined operator< and operator==, even if that was not desired. This has the potential to change the meaning of code in surprising ways.
As a side note - I have been using Boost.Operators to do this, but I am still curious about the standard library.
The way operator overloads for user defined classes was meant to work is via argument dependent lookup. ADL allows programs and libraries to avoid cluttering up the global namespace with operator overloads, but still allow convenient use of the operators; That is, without explicit namespace qualification, which is not possible to do with the infix operator syntax a + b and would instead require normal function syntax your_namespace::operator+ (a, b).
ADL, however, doesn't just search everywhere for any possible operator overload. ADL is restricted to look only at 'associated' classes and namespaces. The problem with std::rel_ops is that, as specified, this namespace can never be an associated namespace of any class defined outside the standard library, and therefore ADL cannot work with such user defined types.
However, if you're willing to cheat you can make std::rel_ops work.
Associated namespaces are defined in C++11 3.4.2 [basic.lookup.argdep] /2. For our purposes the important fact is that the namespace of which a base class is a member is an associated namespace of the inheriting class, and thus ADL will check those namespaces for appropriate functions.
So, if the following:
#include <utility> // rel_ops
namespace std { namespace rel_ops { struct make_rel_ops_work {}; } }
were to (somehow) find its way into a translation unit, then on supported implementations (see next section) you could then define your own class types like so:
namespace N {
// inherit from make_rel_ops_work so that std::rel_ops is an associated namespace for ADL
struct S : private std::rel_ops::make_rel_ops_work {};
bool operator== (S const &lhs, S const &rhs) { return true; }
bool operator< (S const &lhs, S const &rhs) { return false; }
}
And then ADL would work for your class type and would find the operators in std::rel_ops.
#include "S.h"
#include <functional> // greater
int main()
{
N::S a, b;
a >= b; // okay
std::greater<N::s>()(a, b); // okay
}
Of course adding make_rel_ops_work yourself technically causes the program to have undefined behavior because C++ does not allow user programs to add declarations to std. As an example of how that actually does matter and why, if you do this, you may want to go to the trouble of verifying that your implementation does in fact work properly with this addition, consider:
Above I show a declaration of make_rel_ops_work that follows #include <utility>. One might naively expect that including this here doesn't matter and that as long as the header is included sometime prior to the use of the operator overloads, then ADL will work. The spec of course makes no such guarantee and there are actual implementations where that is not the case.
clang with libc++, due to libc++'s use of inline namespaces, will (IIUC) consider that declaration of make_rel_ops_work to be in a distinct namespace from the namespace containing the <utility> operator overloads unless <utility>'s declaration of std::rel_ops comes first. This is because, technically, std::__1::rel_ops and std::rel_ops are distinct namespaces even if std::__1 is an inline namespace. But if clang sees that the original namespace declaration for rel_ops is in an inline namespace __1, then it will treat a namespace std { namespace rel_ops { declaration as extending std::__1::rel_ops rather than as a new namespace.
I believe this namespace extension behavior is a clang extension rather than specified by C++, so you may not even be able to rely on this in other implementations. In particular gcc does not behave this way, but fortunately libstdc++ doesn't use inline namespaces. If you don't want to rely on this extension then for clang/libc++ you can write:
#include <__config>
_LIBCPP_BEGIN_NAMESPACE_STD
namespace rel_ops { struct make_rel_ops_work {}; }
_LIBCPP_END_NAMESPACE_STD
but obviously then you'll need implementations for other libraries you use. My simpler declaration of make_rel_ops_work works for clang3.2/libc++, gcc4.7.3/libstdc++, and VS2012.
I think that the preferred technique is not to use std::rel_ops at
all. The technique used in boost::operator (link) seems to be the usual
solution.
Example:
#include "boost/operators.hpp"
class SomeClass : private boost::equivalent<SomeClass>, boost::totally_ordered<SomeClass>
{
public:
bool operator<(const SomeClass &rhs) const
{
return someNumber < rhs.someNumber;
}
private:
int someNumber;
};
int main()
{
SomeClass a, b;
a < b;
a > b;
a <= b;
a >= b;
a == b;
a != b;
}
The problem with adding the rel_ops namespace, regardless of whether you do it with a manual using namespace rel_ops; or whether you do it automatically as described in the answer by #bames53 is that adding the namespace can have unanticipated side effects on portions of your code. I found this myself just recently as I had been using the #bames53 solution for some time, but when I changed one of my container based operations to use a reverse_iterator instead of an iterator (within a multimap but I suspect it would be the same for any of the standard containers), suddenly I was getting compile errors when using != to compare two iterators. Ultimately I tracked it down to the fact that the code included the rel_ops namespace which was interfering with how reverse_iterators are defined.
Using boost would be a way to solve it, but as mentioned by #Tom not everyone is willing to use boost, myself included. So I implemented my own class to solve the problem, which I suspect is also how boost does it, but I didn't check the boost libraries to see.
Specifically, I have the following structure defined:
template <class T>
struct add_rel_ops {
inline bool operator!=(const T& t) const noexcept {
const T* self = static_cast<const T*>(this);
return !(*self == t);
}
inline bool operator<=(const T& t) const noexcept {
const T* self = static_cast<const T*>(this);
return (*self < t || *self == t);
}
inline bool operator>(const T& t) const noexcept {
const T* self = static_cast<const T*>(this);
return (!(*self == t) && !(*self < t));
}
inline bool operator>=(const T& t) const noexcept {
const T* self = static_cast<const T*>(this);
return !(*self < t);
}
};
To use this, when you define your class, say MyClass, you can inherit from this one to add the "missing" operators. Of course you need to define the == and < operators within MyClass (not shown below).
class MyClass : public add_rel_ops<MyClass> {
...stuff...
};
It is important that you include MyClass as the template argument. If you were to include a different class, say MyOtherClass, the static_cast would be almost certain to give you problems.
Note that my solution is assuming that the == and < operators are defined as const noexcept which is one of the requirements of my personal coding standards. If your standards are different, you would need to modify add_rel_ops accordingly.
In addition, if you are bothered by the use of static_cast, you can change them to be a dynamic_cast by adding
virtual ~add_rel_ops() noexcept = default;
to the add_rel_ops class in order to make it a virtual class. Of course, that will also force MyClass to be a virtual class which is why I do not take that approach.
It's not the nicest, but you can use using namespace std::rel_ops as an implementation detail for implementing the comparison operators on your type. For example:
template <typename T>
struct MyType
{
T value;
friend bool operator<(MyType const& lhs, MyType const& rhs)
{
// The type must define `operator<`; std::rel_ops doesn't do that
return lhs.value < rhs.value;
}
friend bool operator<=(MyType const& lhs, MyType const& rhs)
{
using namespace std::rel_ops;
return lhs.value <= rhs.value;
}
// ... all the other comparison operators
};
By using using namespace std::rel_ops;, we allow ADL to lookup operator<= if it is defined for the type, but fall back onto the one defined in std::rel_ops otherwise.
This is still a pain, though, as you still have to write a function for each of the comparison operators.