How do I forward declare a std function that is templated so that it could be used with various types?
namespace std{
template<typename R, typename T>
class function;
}
and then else where
std::function<void(int)>
Doesn't seem to work.
Edit: Switched over to using boost::function. Still can't get it to compile.
Following the suggestions,I forward declare like this in my header:
namespace boost {
template<typename R>
class function;
}
and use like this again in the header:
boost::function<void(int)> mIdReceiver;
Then in my source/.cpp file I include <boost/function.hpp> and initialize the field.
And I get
mIdReceiver uses undefined class boost::function<void(int)>
error.
You are not allowed to declare or define a (primary) class template in the std namespace in the first place. It will cause the program to have undefined behavior.
This is especially true if you try to do this for a name that is already part of the standard library as is std::function. It will immediately clash with std::function's declaration.
It is surprising that you are trying to do that. There is no valid use case. If you need std::function, then you must #include <functional> and it will be declared properly without you needing to add anything to the std namespace manually.
Related
I have a template function:
namespace Example
{
template<class T>
T Foo() { return T(0); };
}
I would like to use a using statement or similar so that I do not have to prefix the function name with it's namespace when calling it i.e.
template<class T> using Foo = Example::Foo<T>;
However this does not work.
I do not want to use the following approach as it would include everything form the namespace Example:
using namespace Example;
Is there a nice C++ 11 way to create a shortened alias to a function in a namespace?
As for any symbol, you can do using Example::Foo;. This can be used either in namespace scope, or in function scope (this is actually present in C++98, it is not new in C++11). The approach you were trying to do works only for types, while Foo is a function.
I have some code which looks like this:
namespace myLibrary
{
class A
{
public:
struct Nested
{
...
};
...
};
}
In some other parts of the code, I need to access A. Since I like readable code, I also like the using directive:
using myLibrary::A;
...
A a;
Now, at some point I also need to access my nested class, so I want to write something like this:
using myLibrary::A::Nested;
Obviously, the compiler can't know that this is a nested class and not a class member, and gives me an error:
error : using declaration can not refer to class member
What I can't understand is why this does not solve the problem:
using typename myLibrary::A::Nested;
The compiler still gives me the exact same error!
Luckily, I have alternatives:
// Using a typedef
typedef myLibrary::A::Nested Nested;
// Using the new C++11 syntax for type aliasing
using Nested = myLibrary::A::Nested;
but I'd like to understand why the using typename directive did not work. Does it not do what I think it does? Or is it not implemented by compilers? If it is the latter, is there a reason for it?
There is no "using typename directive". There are using-directives and using-declarations.
You're not using any using-directives, and they aren't relevant to the question in any case (they name namespaces, and can't use the typename keyword).
When using-declarations happen to appear within class templates, and happen to name dependent types, they have to use the typename keyword just like anything else that happens to be in a template and happens to name a dependent type.
For example:
template <typename A, typename R>
class Functor : public std::unary_function<A, R>
{
using typename std::unary_function<A, R>::result_type;
using typename std::unary_function<A, R>::argument_type;
public:
result_type operator() (argument_type) {}
};
In your situations, the namespace-declaration does not appear to be a part of the body of a class template, in fact it appears to be at namespace scope, in which case attempting to name a class member (doesn't matter if it's a type or a function or whatever) violates 7.3.3[namespace.udecl]/8
A using-declaration for a class member shall be a member-declaration
as the compiler correctly diagnosed with "error : using declaration can not refer to class member"
A using declaration referring to a namespace member A may only appear at namespace or local scope.
A using declaration referring to a class member Nested may only appear at class scope (along with member declarations), in a class derived from Nested. In fact, such using declarations are grammatically considered to be member declarations. They are used to adjust access qualification, and (with typename) to allow members of type-dependent bases to be used without qualification. These are specific use cases, so member using declarations are a bit specialized.
A nested class is a member of its enclosing class. You should generally avoid using class enclosures as a substitute for namespaces. Metaprogramming provides some exceptions to the rule, but in those cases you still wouldn't use using declarations, at least at namespace scope, because namespaces cannot be templated. Inheriting from an empty metaprogramming class is viable, but do mind the spaghetti.
The using directive is a different beast. It looks like using namespace and it links one namespace to another as a fallback path in name lookup.
I am writing a C++ class which represents an arithmetic type (a c++ wrapper around mpfr), and I'd like to support some functions found in <cmath> (I'll take std::sqrt as an example).
So I have the following class:
namespace ns
{
class MyClass
{
/* ... */
public:
friend MyClass sqrt(const MyClass& mc);
};
}
And I can use it this way:
MyClass c;
/* ... */
MyClass d = ns::sqrt(c);
MyClass e = sqrt(c); // Apparently I don't have to specify ns::
But I cannot use it this way:
MyClass f = std::sqrt(c);
Compiler (g++ (Debian 4.7.2-5)) error is: "no matching function for call to sqrt(ns::MyClass&)".
This is normal, but it's a problem to me. I need this to be valid, because MyClass is supposed to be used into existing template functions (that I'm not supposed to modify). For example:
template <typename T>
void func(T a)
{
/* ... */
T c = std::sqrt(a);
/* ... */
}
int main()
{
func<float>(3);
func<MyClass>(MyClass(3));
/* ... */
}
The following piece of code actually resolve my problem:
namespace std
{
using ns::sqrt;
}
But adding things into the std namespace seems very unnatural to me. I am afraid to run into unexpected troubles later, doing this.
Is it safe ? If not, why ?
Is there a better alternative ?
Adding stuff to namespace std is prohibited by the standard. The correct way to tackle this problem is normally seen with swap (that is available in the std namespace, but that can be specialized by user-defined types to work more efficiently): when a template function needs to use e.g. sqrt, it will do
using std::sqrt;
a=sqrt(b);
This way, for "regular" types it will use std::sqrt ("taken in" by the using statement), while for your type your overload will prevail due to Koenig lookup (which, incidentally, is the reason of the behavior you observed at // Apparently I don't have to specify ns::).
It’s not safe, because it’s not legal (§17.6.4.2.1):
The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.
So you may add specialisations for your own types. You may not add overloads (or indeed anything else).
Your current code is the correct way of doing this.
The alternative, within generic functions, is to do this:
template <typename T>
void func(T a)
{
using std::sqrt;
/* ... */
T c = sqrt(a);
/* ... */
}
And defining additional things into the std-namespace is not safe in general (and not strictly legal).
Not so good an idea to put it in std namespace.
Since you have your own namespace, you could import sqrt into your namespace and add specialized sqrt functions:
namespace ns {
using std::sqrt;
MyClass sqrt(const MyClass &)
}
ns::sqrt(...);
I'm writing a class (in a header file) that requires the following method:
static const foo::bar::clz* getSomething(void);
As I don't want to pollute the header file with an #include I choose to forward declare clz:
namespace foo
{
namespace bar
{
class clz;
}
}
But that's rather clumsy too. Is there a cuter way of doing this in C++11? Something along the lines of
class foo::bar::clz;
It would be nicer still if you didn't have to anticipate whether or not it's implemented as a class, struct or union. Have the C++11 grammarians covered that one too? (typename auto could be a candidate but I'm not an expert in C++ grammar).
The nested namespaces can't be avoided.
As for class vs. struct vs. union, partially: class and struct can be used interchangeably. If it's a union, it must be declared as such.
I was trying to come up with a hack to test if std::isnan is defined without special casing compilers in the preprocessor, and came up with the following, which I was expecting to work fine.
#include <cmath>
#include <type_traits>
namespace detail {
using namespace std;
struct dummy {};
void isnan(dummy);
//bool isnan(float); // Just adding this declaration makes it work!
template <typename T>
struct is_isnan_available {
template <typename T1>
static decltype(isnan(T1())) test(int);
template <typename>
static void test(...);
enum { value = !std::is_void<decltype(test<T>(0))>::value };
};
}
int main() {
return detail::is_isnan_available<float>::value;
}
Turns out it doesn't detect it. I know for certain std::isnan is defined on ideone, because I tested that manually.
And when I uncomment the marked line above, it works.
What am I missing here? What explains this behaviour?
The thing is, that the using directive doesn't add members to the current namespace, so the std:: members could still be hidden by declarations in this namespace.
using std::isnan would instead behaves as if the members of the imported namespace were added to the namespace enclosing both the use-location and the imported namespace. The using declaration is a normal declaration in the namespace, so can take part in overload resolution with the declarations that follow.
However, as pointed out in the comments, that would produce an error if the function does not exist. To work around that you need to put it out of your detail:: namespace then. That should work, because the imported definition would be at the same level as the dummy overload. You can take the overload to the global namespace, or you can make an auxiliary namespace (in the global namespace) and import both.
I solved this problem for the set of POSIX thread-safe APIs which supersede non-thread-safe standard functions: C++11 alternative to localtime_r . This code detects whether an API is defined in the global namespace, and if it does not exist, selects a custom workaround.