I'm trying to write a macro to make a specific usage of callbacks in C++ easier. All my callbacks are member functions and will take this as first argument and a second one whose type inherits from a common base class.
The usual way to go is:
register_callback(boost::bind(&my_class::member_function, this, _1));
I'd love to write:
register_callback(HANDLER(member_function));
Note that it will always be used within the same class.
Even if typeof is considered as a bad practice, it sounds like a pretty solution to the lack of __class__ macro to get the current class name.
The following code works:
typedef typeof(*this) CLASS;
boost::bind(& CLASS :: member_function, this, _1)(my_argument);
but I can't use this code in a macro which will be given as argument to register_callback.
I've tried:
#define HANDLER(FUN) \
boost::bind(& typeof(*this) :: member_function, this, _1);
which doesn't work for reasons I don't understand. Quoting GCC documentation:
A typeof-construct can be used anywhere a typedef name could be used.
My compiler is GCC 4.4, and even if I'd prefer something standard, GCC-specific solutions are accepted.
Your problem might be that typeof yields my_class&. It appears to work with boost::remove_reference:
#include <boost/bind.hpp>
#include <boost/type_traits.hpp>
#include <iostream>
struct X
{
void foo(int i) { std::cout << i << '\n'; }
void bar() {boost::bind(&boost::remove_reference<typeof(*this)>::type::foo, this, _1)(10); }
};
int main()
{
X x;
x.bar();
}
It might be more portable to use BOOST_TYPEOF, and in C++0x decltype
Related
For many times now, I have had problems with the declaration and definition order in C++:
struct A {
void Test() { B(); }
};
void B() {
A a;
}
Of course this can be solved by predeclaring B(). Usually this is good enough to solve any of these problems. But when working with module based header-only libraries or similarily complex include systems, this declaration/definition concept can be really painful. I have included a simple example below.
Nowadays most modern language compilers do a two-pass over the source files to build the declarations in the first pass and process the definitions in the second one. Introducing this scheme into C++ shouldn't break any old code either. Therefore,
Why hasn't this, or a similar approach, been introduced into c++ already?
Are there any relevant clauses in the current standard inhibiting this approach?
Example
This is an example of a module based header library, which has blocking includes because of missing predeclarations. To solve this, the user of the library would have to predeclare the "missing" classes, which is not feasible.
Of course this problem might be solved by using a common include header that orders all declarations before definitions, but with a two-pass this code would also work, no modification required.
oom.h
#pragma once
#include "string.h"
struct OOM {
String message;
};
string.h
#pragma once
#include "array.h"
struct String {
Array data;
};
array.h
#pragma once
struct Array {
void Alloc();
};
#include "oom.h"
void Array::Alloc() { throw OOM(); }
str_usage.cpp
#include "string.h"
int main() {
String str;
}
void f(int);
void g() { f(3.14); }
void f(double);
g currently calls f(int), because it's the only f visible. What does it call in your world?
If it calls f(double), you just broke copious existing code.
If you came up with some rules to make it still call f(int), then that means if I write
void g2() { f2(3.14); }
void f2(double);
and then introduce a worse match for the argument - say, void f2(int); before g2, g2 will suddenly start calling the wrong thing. That's a maintainability nightmare.
A much simpler solution is to separate class definitions from function definitions:
struct A {
void Test();
};
struct B {
A a;
};
inline void A::Test() {
B();
}
There are ambiguities in the C++ grammar that can only be resolved if you know what an identifier refers to.
For example:
a * b;
can be either a multiplication if a is a variable, or a pointer declaration if a is a type. Each of these leads to a different parse tree, so the parser must know what a is.
This means that parsing and name resolution cannot be performed in separate passes, but must be done in one pass, leading to the requirement to pre-declare names.
everyone.
I am debugging some problem of type mismatch of a heavily templated class. I would like to know c++ type information during compilation, so I write this:
#pragma message typeinfo(var)
It just do not work.
So I am here asking for some help. I am not sure if it is possible. But I think the compiler must know the type information during compilation.
The preprocessor is not going to help you much itself at compile time. It's job is preprocessing, which happens before compile time.
If the idea is to output type information at compile time then try the following
template <typename...> struct WhichType;
class Something {};
int main() {
WhichType<Something>{};
}
Live example here. When you compile this you should get an error that gives you the type of whatever is inside the templates when trying to instantiate WhichType. This was a neat trick I picked up from Scott Meyers' Effective Modern C++ book. It seems to work perfectly on most mainstream compilers that I have encountered so far.
If you want to get the type information at runtime
#include <iostream>
#include <typeinfo>
using std::cout;
using std::endl;
int main() {
auto integer = int{};
cout << typeid(integer).name() << endl;
}
Note Don't get too comfortable with RTTI (RunTime Type Information) via typeid, C++ also offers several compile time type introspection utilities http://en.cppreference.com/w/cpp/header/type_traits.
I use a type printer helper function, which simply bases on the gcc predefined macro __PRETTY_FUNCTION__. Simply write a templated function which eats everthings and call it from the point where you need to know which type your template expands to. For me it was very helpful to use such a function in case of SFINAE problems and others.
template <typename ... T>
void TemplatePrint(T ... args )
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
int main()
{
auto any = std::tuple_cat( std::tuple<int, double>{}, std::tuple<std::string>{} );
TemplatePrint( any );
}
You did not tag your question to a specific compiler, so you maybe need to search for equivalents on other compilers.
On C++ con some year ago a talk was about:
https://baptiste-wicht.com/posts/2016/02/use-templight-and-templar-to-debug-cpp-templates.html. Maybe this will help to get strange template problems solved.
A bit of background: I want to write a tool that compiles a bunch of named things into C++ code. The list changes and I don't want to rebuild the world when that happens. Despite that, I want to address the compiled code by (literal) name.
As an example of something that's not quite right, I could have put this in a header:
template<int name> void func();
Then my tool can generate code like:
template<> void func<1>() { ... }
template<> void func<2>() { ... }
template<> void func<3>() { ... }
Now I can call these by "name" anywhere without pre-declaring each one.
I want to do this, but with something more descriptive than integers. Ideally I want text of some form. What I need is something like:
#define FUNC_WITH_NAME(name) func_named_ ## name
That doesn't quite work, though: it needs a declaration of func_named_whatever.
The next try is no good either (and it's GCC-specific):
#define FUNC_WITH_NAME(name) ({extern void func_named_ ## name; func_named_ ## name;})
It fails because, if it's used inside a namespace, then it ends up looking for func_named_whatever in that namespace.
The best I've come up with is this:
template<char... tagchars> int tagged();
namespace NS {
int caller()
{
return tagged<'n', 'a', 'm', 'e'>();
}
}
This works, but it's ugly (and it's not obvious how to turn a string literal into a parameter pack without jumping through nasty hoops). Also, if the symbol doesn't resolve, then the error message from g++ is terrible:
In function `NS::caller()':
named_symbol.cpp:(.text+0x5): undefined reference to `int tagged<(char)110, (char)97, (char)109, (char)101>()'
collect2: error: ld returned 1 exit status
The only thing that I've come up with is a gcc extension:
extern void func_named_whatever __asm__("func_named_whatever");
But this is no good as a template argument (it only affects calls to that function; it does not affect use of magic asm-ified symbols when they're template arguments), and it defeats any link-time type checking because it turns off mangling.
Now I can call these by "name" anywhere without pre-declaring each one.
To call any function at compile time, you need to forward-declare it.
Because you want to call them at compile time, there's no need to use string literals. And you can only do this using preprocessor, not templates, because you cannot specify identifier names for templates (in C++03, at least).
Example:
#include <iostream>
#define CALL_FUNC(func, args) name_ ##func args;
void name_func1(){
std::cout << "func1" << std::endl;
}
void name_func2(int a){
std::cout << "func2:" << a << std::endl;
}
int main(int argc, char** argv){
CALL_FUNC(func1, ());
CALL_FUNC(func2, (46));
return 0;
}
You can forward-declare function within function body:
#include <iostream>
int main(int argc, char** argv){
void name_func(int);
name_func(42);
return 0;
}
void name_func(int arg){
std::cout << "func1:" << arg << std::endl;
}
So, technically, you don't even need to use preprocessor for that.
You cannot avoid forward-declaration, unless all functions arguments are known as well as their types, in which case you can hide forward-declaration with macros.
#include <iostream>
#define FUNC_NAME(func) name_ ##func
#define CALL_VOID_FUNC(func) { void FUNC_NAME(func)(); FUNC_NAME(func)(); }
int main(int argc, char** argv){
CALL_VOID_FUNC(func1);//not forward declared
return 0;
}
void name_func1(){
std::cout << "func1" << std::endl;
}
Or if you want to specify function argument types every time you call functions and know number of arguments:
#include <iostream>
#define FUNC_NAME(func) name_ ##func
#define CALL_FUNC_1ARG(func, type1, arg1) { void FUNC_NAME(func)(type1); FUNC_NAME(func)(arg1); }
int main(int argc, char** argv){
CALL_FUNC_1ARG(func1, int, 42);
return 0;
}
void name_func1(int arg){
std::cout << "func1:" << arg << std::endl;
}
Or if your function can take variable number of arguments. (parsing varargs is fun):
#include <iostream>
#define FUNC_NAME(func) name_ ##func
#define CALL_FUNC_VARIADIC(func, args) { void FUNC_NAME(func)(...); FUNC_NAME(func)args; }
int main(int argc, char** argv){
CALL_FUNC_VARIADIC(func1, (42, 43, 44));
return 0;
}
void name_func1(...){
//std::cout << "func1:" << arg << std::endl;
}
If you want to use STRINGS (as in "func1"), then you are trying to locate function at run time, not at compile time, even if you don't really think so. That's because "funcname" isn't that different from (std::string(std::string("func") + std::string("name")).c_str()) - it is pointer to memory region with character. Some compiler might provide extensions to "unstringize" string, but I'm not aware of such extensions.
In this case your only option is to write either preprocessor or code-generator, that'll scan some kind of text template (that lists functions) every time you build the project, and converts it into .h/.cpp files that are then compiled into your project. Those .h/.cpp files shoudl build function table (name to function pointer map) that is then used "behind the scenes" in your project. See Qt MOC for a working example. That'll require recompilation every time you add new function to template.
If you do not want recompilation for every new function prototype (although you can't add call to a new function without recompiling project, obviously), then your only choice is to embed scripting language into your application. This way you'll be able to add functions without recompiling. At we momen, you can embed lua, python, lisp(via ecl) and other languages. There's also working C++ interpreter, although I doubt it is embeddable.
If you do not want to use any options I listed, then (AFAIK) you cannot do that at all. Drop some requirement ("no recompilation", "no forward declaration", "call using string literal") and try again.
Can I reliably turn a string literal into a symbol name using the C macro language?
No. You can turn string literal into identifier to be processed by compiler (using stringize), but if compiler doesn't know this identifier at this point of compilation, your code won't compile. So, if you're going to call functions this way using their names, then you'll have to insure that they all were forward-declared before. And you won't be able to locate them at runtime.
C++ doesn't store names for functions and variables in compiled code. So you can't find compiled function by its name. This is because C++ linker is free to eliminate unused functions completely, inline them or create multiple copies.
What you CAN do:
Create a table of functions that you want to address by name (that maps function name to function pointer), then use this table to locate functions. You'll have to manually register every function you want to be able to find in this table. Something like this:
typedef std::string FunctionName;
typedef void(*Function)(int arg);
typedef std::map<FunctionName, Function> FunctionMap;
FunctionMap globalFunctionMap;
void callFunction(const std::string &name, int arg){
FunctionMap::iterator found = globalFunctionMap.find(name);
if (found == globalFunctionMap.end()){
//could not find function
return;
}
(*found->second)(arg);
}
Use dynamic/shared libraries. Put functions you want to be able to address into shared library (extern "C" __declspec(dllexport) or __declspec(dllexport)), mark them for export then use operating system functions to locate function within library (dlsym on linux, GetProcAddress of windows). Afaik, you might be able export functions from exe as well, so you might be able to use this approach without additional dlls.
Embed scripting language into your application. Basically, in most scripting languages you can locate and call function by its name. That'll be function declared within scripting language, obviously, not a C++ function.
Write code preprocessor that'll scan your project for "named" functions and build table of those function (method #1) somewhere automatically. Can be very difficult, because C++ is not that easy to parse.
The ideal solution would be N3413, but that's a long way off.
With thanks to 0x499602d2 and Using strings in C++ template metaprograms, here's a so-so answer:
template<char... str>
struct tag
{
template<char first>
struct prepend
{
typedef tag<first, str...> type;
};
};
template<typename Tag>
void func();
#define PREPARE_STR_TAGGER(str) \
template<int charsleft> \
struct tagger_for_##str \
{ \
typedef typename \
tagger_for_##str<charsleft-1>::type:: \
template prepend<(#str)[sizeof(#str)-1-charsleft]>::type type; \
}; \
template<> \
struct tagger_for_##str<0> \
{ \
typedef tag<> type; \
};
#define STRING_TO_TAG(str) tagger_for_##str<sizeof(#str)-1>::type
namespace SHOULD_NOT_MATTER {
PREPARE_STR_TAGGER(some_string);
void test()
{
func<STRING_TO_TAG(some_string)>();
}
}
Downsides:
It's awkward to use: you need to use PREPARE_STR_TAGGER at namespace (or maybe class) scope.
It's probably unfriendly to compile time.
The linker errors it generates are awful.
Some kind of decent hash function based on constexpr would work, but it would result in even more awful error messages.
Improvements are welcome.
Dear all, I would like to call a member function (that expects a reference) for each object of (let's say) a vector that is a member of the same class, as the following code shows:
#include <functional>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
struct Stuff {
double x;
};
class Test {
public:
void f1(Stuff & thing);
void f2(void);
vector<Stuff> things;
};
void Test::f1(Stuff & thing) {
; // do nothing
}
void Test::f2(void) {
for_each(things.begin(), things.end(), f1);
}
int main(void)
{
return 0;
}
This codes gives me a compiler error related to unresolved overloaded function type . I have tried also with bind, but it seems that the references requisite in f1 is one problem. I know I am missing something important here, so I take this opportunity to solve my problem and to learn. At the moment, I can't install boost, but I would like to know also if boost is useful to solve this problem. Thanks in advance.
The function you want to call cannot be simply identified by f1 but should be referred to as &Test::f1 (as in : member function f1 of class Test)
Function f1 does not take a single argument : as any non-static member function it has an implicit this parameter of type Test * const
Finally, a standard bind won't be able to do the trick because it doesn't handle parameters passed by reference.
Boost.Bind would indeed be a great option :
std::for_each(things.begin(), things.end(), boost::bind(&Test::f1, this, _1));
I am a fairly experienced .net developer but new to Arduino and C/C++ and I am trying to create my first library which is a simple driver for a 7 segment led display. I have many obtuse compiler errors but in the spirit of one thing at a time this is the first. I want to add a parameterless constructor to my class and when I do library compiles fine but when I try to use the class in a sketch the compiler gives me the rather obtuse "request for member 'setDigit' in 'sevenSegmentLed', which is of non-class type 'SevenSegmentLed()"
The simplest example code is below:
#ifndef SevenSegmentLed_h
#define SevenSegmentLed_h
#include "Arduino.h"
class SevenSegmentLed
{
public:
void setDigit(int digit);
SevenSegmentLed();
};
#endif
#include "Arduino.h"
#include "SevenSegmentLed.h"
SevenSegmentLed::SevenSegmentLed()
{
}
void SevenSegmentLed::setDigit(int digit)
{
}
#include "SevenSegmentLed.h"
SevenSegmentLed sevenSegmentLed();
void setup() {
sevenSegmentLed.setDigit(4);
}
void loop() {
// put your main code here, to run repeatedly:
}
However if I change the constructor signature to: SevenSegmentLed(int wtf); and instantiate it thus: SevenSegmentLed sevenSegmentLed(1); it compiles just fine. So as the parameter says, WTF?
I believe the issue is that this:
SevenSegmentLed sevenSegmentLed();
Is interpreted as a function declaration and not an initialization. Note that you can't have this problem with c# because you have the new keyword disambiguating for you so this particular problem is avoided.
To fix you can do 2 things:
Use the c++ uniform initialization syntax (introduced in newer c++ standard to avoid exactly your issue):
SevenSegmentLed sevenSegmentLed{};
Or use the following syntax:
SevenSegmentLed sevenSegmentLed;
The main benefit of the uniform syntax is that it's uniform. So for example if you have a constructor that takes an integer you can write it like this:
SevenSegmentLed sevenSegmentLed{1};
Generally speaking the uniform initialization syntax is preferable, when I was writing the c++ guideline at my work (mostly c# and php guys) I decided to go with this as it's the most clear and unambiguous.