Value not usable in constant expression alternative pattern - c++

I am looking for an alternative c++ pattern to achieve this:
Read from an option from a file (let's say its either A or B).
In a cycle I want to repeat a call to a template function depending on the option, but I don't want to check the value each time, instead, I want the compiler to generate both possibilities and choose the one with template A if the option is set to A, and with template B if the option is set to B.
If i do this though:
Option option = readFromFile("AorB");
for(int i = 0; i < 100000; ++i)
{
performOperation<option>(); // Long but fast function I don't want to define twice
}
I get the following error:
error: the value of 'option' is not usable in a constant expression
How can I achieve the desired behaviour?

To make the code weirder and more meta ;) you could play a bit with variadic templates, lambdas and constexpr implicit cast:
#include <iostream>
template <char C>
struct Option {
constexpr operator char() {
return C;
}
};
template <char Opt>
void performOperation() {
std::cout << Opt << std::endl;
}
template <char... Options>
void runOption() {
char optionFromFile = 'a';
int dummy[] = {([](auto option, char chosen) {
if (chosen == option) {
for(int i = 0; i < 5; ++i) {
performOperation<option>();
}
}
}(Option<Options>{}, optionFromFile), 0)...};
static_cast<void>(dummy);
}
int main() {
runOption<'a', 'b'>();
}
[live demo]
Have fun!

As others have mentioned, you can't pass a variable to something that expects a compile time constant.
If you've got something that is either "A" or "B" and you're worried about checking for that each time then you could expand the loop/condition yourself:
Option option = readFromFile("AorB");
if(option.isA())
{
for(int i = 0; i < 100000; ++i)
{
performOperationA();
}
else
{
for(int i = 0; i < 100000; ++i)
{
performOperationB();
}
}

If you want the operation to select the behavior at runtime, then you may want to create a class to encapsulate the behavior that varies. Next create an instance of the class once based on the option value A or B. Then inside the loop, you pass the class instance to operation.
I've provided an example below that implements OptionA and OptionB in a class hierarchy. If you do it this way, then you don't even need a template at all. But you didn't provide much detail on how the behavior of your operation varies, so I didn't want to assume too much about what you have to work with. The template is only required if you have two unrelated classes that implement an identical interface.
#include <iostream>
#include <string>
class OptionType {
public: virtual int calculate( int x ) = 0;
};
class OptionA :public OptionType {
public: int calculate( int x ) { return x+99; }
};
class OptionB : public OptionType {
public: int calculate( int x ) { return x*100; }
};
template<class T>
void performOperation( T& option, int x ) {
// your performOperation is a long function
// this one is short but shows how the behavior can vary by option
std::cout << option.calculate( x ) << std::endl;
}
int main( int argc, char* argv[] )
{
// Option option = readFromFile("AorB");
// pass A or B from the command line
char option = (argc > 1) ? argv[1][0] : 'A'; // your code reads this from a file
OptionType* optionObject;
if( option == 'A' ) optionObject = new OptionA();
else optionObject = new OptionB();
for(int i = 0; i < 10; ++i)
{
performOperation( *optionObject, i );
}
}

you can't because the option is a variable, and a template is compile time. the performOperation needs to receive a constant value on the <>.
and since the operations occours on runtime - you need an if.
But you could use the branch prediction to do less work - if you sort the vector before passing to for / if call(value) else call_2(value), it would run much faster.

Template arguments must be known at compile time. At run time, it's too late to instantiate new instances of a template. You will need to force the generation of each instance that may be required at run time and implement some form of dispatching. The simplest approach is to have a dispatching function with a switch. For example :
enum class Option {
Opt1,
Opt2,
Opt3
};
template<Option opt>
void Operation() {}
void performOperation(const Option opt)
{
switch (opt)
{
case(Option::Opt1):
Operation<Option::Opt1>();
break;
case(Option::Opt2):
Operation<Option::Opt2>();
break;
case(Option::Opt3):
Operation<Option::Opt3>();
break;
default:
// Handle however you want
}
}
Another solution would use a map of std::function :
#include <map>
#include <functional>
enum class Option {
Opt1,
Opt2,
Opt3
};
template<Option opt>
void Operation() {}
const std::map<Option, std::function<void()>> func_map = {
{ Option::Opt1, []{Operation<Option::Opt1>(); }},
{ Option::Opt2, []{Operation<Option::Opt2>(); }},
{ Option::Opt3, []{Operation<Option::Opt3>(); }}
};
void performOperation(const Option opt)
{
func_map.at(opt)();
}

If I understood the question correctly.
You could try this way:
for(int i = 0; i < 100000; ++i)
{
#ifdef A
read("A");
#endif
#ifdef B
read("B");
#endif
}
and at compiler level you can choose:
g++ main.cpp -D A
or
g++ main.cpp -D B

Related

In C++, how can one map between enum values and data types, so the types can be used in templates?

How can one do this, which is obviously impossible C++, in real C++?:
Type decodeUiEnum(UiEnum myEnum) { // impossible: cannot return a data type
// one switch statement to rule them all
switch(myEnum) {
case USER_SELECTED_GREYSCALE: return GreyscalePixel;
case USER_SELECTED_RGB: return RgbPixel;
...
}
}
void doSomeGraphicsMagic1(UiEnum myEnum) {
...
Foo<decodeUiEnum(myEnum)> a(...); // impossible: type not available at compile
// time
...
}
void doSomeGraphicsMagic2(UiEnum myEnum, int blah) {
...
Bar<int, decodeUiEnum(myEnum)> b(...); // impossible
...
}
and the like, so you can just add new types to the top switch statement and not have to modify the other code below it, so long as that code is suitably generic of course? As otherwise, you would need a switch statement within each function to do the necessary type mapping into the templates, which is not as much maintainable code, and lots of duplication. So more generally - if this is approaching it the wrong way, how do we fulfill that intended property of the code?
That is, what I want to do is, in a function taking an enum as parameter, instantiate a template type where the template parameter depends on the enum, without having a switch-on-enum in every function.
Yes it is actually possible.
Trick is based on partial template specification, this approach used by std::get
For example:
#include <iostream>
// specify an enumeration we will use as type index and related data types
enum class UiEnum {
GRAY_SCALE,
RGB_PIXEL
};
struct GreyscalePixel;
struct RgbPixel;
// make base template class
template<UiEnum _EV>
struct ui_enum_type {
};
// do partial type specification trick
// insert typedefs with data type we need for each enumeration value
template<>
struct ui_enum_type<UiEnum::GRAY_SCALE> {
typedef GreyscalePixel pixel_type;
};
template<>
struct ui_enum_type<UiEnum::RGB_PIXEL> {
typedef RgbPixel pixel_type;
};
// demo classes to demonstrate how trick is working at runtime
template<typename T>
struct demo_class {
};
template <>
struct demo_class<GreyscalePixel> {
demo_class()
{
std::cout << "GreyscalePixel" << std::endl;
}
};
template <>
struct demo_class<RgbPixel> {
demo_class()
{
std::cout << "RgbPixel" << std::endl;
}
};
// use swithc trick
static void swich_trick(std::size_t runtimeValue)
{
switch( static_cast<UiEnum>(runtimeValue) ) {
case UiEnum::GRAY_SCALE: {
demo_class< ui_enum_type<UiEnum::GRAY_SCALE>::pixel_type > demo1;
}
break;
case UiEnum::RGB_PIXEL: {
demo_class< ui_enum_type<UiEnum::RGB_PIXEL>::pixel_type > demo2;
}
break;
}
}
int main(int argc, const char** argv)
{
// Do runtime based on the trick, use enum instead of data type
for(std::size_t i=0; i < 2; i++) {
swich_trick(i);
}
return 0;
}
In any case my suggestion - use classic polymorphism instead of template meta-programming over complication. Most modern compilers doing de-virtualization during optimization. For example:
#include <iostream>
#include <memory>
#include <unordered_map>
enum class UiEnum {
GRAY_SCALE,
RGB_PIXEL
};
class GraphicsMagic {
GraphicsMagic(const GraphicsMagic&) = delete;
GraphicsMagic& operator=(const GraphicsMagic&) = delete;
protected:
GraphicsMagic() = default;
public:
virtual ~GraphicsMagic( ) = default;
virtual void doSome() = 0;
};
class GreyscaleGraphicsMagic final: public GraphicsMagic {
public:
GreyscaleGraphicsMagic():
GraphicsMagic()
{
}
virtual void doSome() override
{
std::cout << "GreyscalePixel" << std::endl;
}
};
class RgbGraphicsMagic final: public GraphicsMagic {
public:
RgbGraphicsMagic():
GraphicsMagic()
{
}
virtual void doSome() override
{
std::cout << "RgbPixel" << std::endl;
}
};
int main(int argc, const char** argv)
{
std::unordered_map< UiEnum, std::shared_ptr< GraphicsMagic > > handlers;
handlers.emplace(UiEnum::GRAY_SCALE, new GreyscaleGraphicsMagic() ) ;
handlers.emplace(UiEnum::RGB_PIXEL, new RgbGraphicsMagic() );
for(std::size_t i=0; i < 2; i++) {
handlers.at( static_cast<UiEnum>(i) )->doSome();
}
return 0;
}
You could use std::variant, and then have consuming code std::visit that variant.
First we want a template for "pass a type as a parameter"
template <typename T>
struct tag {
using type = T;
};
Then we define our variant and the factory for it.
using PixelType = std::variant<tag<GreyscalePixel>, tag<RgbPixel>>;
PixelType decodeUiEnum(UiEnum myEnum) {
switch(myEnum) {
case USER_SELECTED_GREYSCALE: return tag<GreyscalePixel>{};
case USER_SELECTED_RGB: return tag<RgbPixel>{};
...
}
}
Now our methods can be written as visitors over PixelType
void doSomeGraphicsMagic1(UiEnum myEnum) {
std::visit([](auto t){
using Pixel = decltype(t)::type;
Foo<Pixel> a(...);
}, decodeUiEnum(myEnum));
}
int doSomeGraphicsMagic2(UiEnum myEnum, int blah) {
return std::visit([blah](auto t){
using Pixel = decltype(t)::type;
Bar<int, Pixel> a(...);
return a.frob();
}, decodeUiEnum(myEnum));
}

How to avoid typeid with better abstraction?

I am using typeid in my code, but it seems to me that the code can be cleaner if I avoid typeid.
If we want to store the type of the class, why would we choose an object-oriented language in the first place?
But I see this pattern over and over again and I do not know how to avoid it.
So I am thinking if this code can be written cleaner with a better abstraction?
Here is the code:
class A {
public:
string type;
};
template <typename T>
class B : public A {
public:
B() {
type = typeid(T).name();
}
};
class Registry {
private:
std::vector<A *> list;
public:
void append(A * a) {
int found = 0;
for (A * el : list) {
if (a->type == el->type) {
found = 1;
break;
}
}
if (!found)
list.push_back(a);
}
int size() {
return list.size();
}
};
int main(int argc, char **argv) {
Registry reg;
A * b_int1 = new B<int>();
A * b_int2 = new B<int>();
A * b_float = new B<float>();
reg.append(b_int1);
reg.append(b_int2);
reg.append(b_float);
cout << reg.size() << endl;
return 0;
}
The output is 2. (which is the expected result)
Basically we do not want to store two object of the same type in a list.
If you don't want visitors, but you'd like a quick RTTI, I'd suggest looking into this paper: http://www.stroustrup.com/fast_dynamic_casting.pdf
The idea is:
Each class is assigned a distinct prime number for it's own type (e.g., A::my_type = 2; B::my_type = 3)
Then each class is additionally assigned the product of its type and base class values if any (e.g., A::can_cast = A::my_type; B::can_cast = B::my_type * A::can_cast; )
This solves the is_same_dynamic(), is_base_dynamic() problems elegantly: former becomes ==, latter becomes %.
To check whether or not an object belongs to a class derived from a given class, one might use the dynamic_cast<T*> and compare the result with nullptr. Unfortunately, given that we need to check this fact to the unknown type, we are forced to implement such comparison method once per each descendant of class A, but this may be simplified using #define.
Summing up, I would probably write it like this:
#define TYPE_COMPARISON \
virtual bool compare(A* rhs) \
{ \
return dynamic_cast<decltype(this)>(rhs) != nullptr; \
}
class A {
public:
TYPE_COMPARISON
};
template <typename T>
class B : public A {
public:
TYPE_COMPARISON
};
class Registry {
private:
std::vector<A *> list;
public:
void append(A * a) {
int found = 0;
for (A * el : list) {
if (a->compare(el) && el->compare(a)) {
found = 1;
break;
}
}
if (!found)
list.push_back(a);
}
int size() {
return list.size();
}
};
Also, such method allows you to define whether or not a particular descendant class should be treated as being distinct with its parent.

A function where the main variables type is determined at run-time

I have a kindof simple problem I dont know how to solve, its from using python & becoming accustomed with working with variables where the data type doesn't matter . I am working with the windows Task Scheduler & its millions of objects it has, ITask...this ITask...that.
So I have a function, & depending on the parameter triggerType (an enumeration var), the variable trigger will either be of type ITimeTrigger or IBootTrigger ... ugh this is hard to explain in text, if you look at the code below it will be easy to see what my problem is.
Its ALOT easier to understand my issue by looking at my example below:
enum meh { I_WANT_A_INT = 50001, I_WANT_A_FLOAT };
bool foo( meh triggerType )
{
switch ( triggerType )
{
case I_WANT_A_INT:
{
int trigger = 10;
}
break;
case I_WANT_A_FLOAT:
{
float trigger = 10.111;
}
break;
default:
{
double trigger = 11;
}
break;
}
trigger = 5 * trigger ; // Compile error because trigger is not declared
cout << trigger << endl;
}
The solutions I know I can use are:
- I can overload the function & have one for the ITimeTrigger(int) action & another for IBootTrigger(float). This is something I really dont want to do because the function is really long with alot of repeating code between them.
- ITimeTrigger & IBootTrigger both inherit from the same object ITrigger, so I could declare the trigger var outside the switch as ITrigger, then cast to the object I need within the switch. This will work now, but when I
extend this function to schedule a different kind of task trigger will not inherit from ITrigger (win32 semantics again) so this solution wont work.
How can I declare the variable trigger (whose data type will be determined at run time) so I can then work with the var later on in the function?
You can use templates to avoid the code duplication. For example, the above can be rewritten as:
// Common code goes here:
template<typename TriggerType>
void bar(TriggerType trigger)
{
trigger *= 5;
std::cout << trigger << std::endl;
}
// Differing code goes here:
void foo(meh trigger_type)
{
switch (trigger_type) {
case I_WANT_A_INT:
bar(10); // invokes the int version
break;
case I_WANT_A_FLOAT:
bar(10.111f); // invokes the float version; note the use of 'f'
break;
default:
bar(11.0); // invokes the double version; note the use of '.0' and lack of 'f'
}
}
For those types with radically different behavior, you can also have specialized instantiations of bar.
This doesn't really make sense in C++; types are determined at run-time. Whilst you could create a hierarchy of classes that behave similarly to the built-in types, overloading operator*, etc. for them polymorphically, I would question why you want the ability to mix primitive types like this?
If you want different versions of the function for different types, but without code duplication, then you probably want to look at using function templates. See e.g. http://www.parashift.com/c++-faq-lite/templates.html.
#include <iostream>
using namespace std;
enum meh { i_want_a_int = 50001, i_want_a_float };
template< class Number >
bool bar( Number trigger )
{
trigger *= 5;
cout << trigger << endl;
return true;
}
bool foo( meh triggerType )
{
switch ( triggerType )
{
case i_want_a_int:
return bar<int>( 10 );
case i_want_a_float:
return bar<float>( 10.111f );
default:
return bar<double>( 11.0 );
}
}
int main()
{
foo( i_want_a_float );
}
By the way, you can greatly reduce the chance of inadvertent text replacement by reserving ALL_UPPERCASE identifiers for macros.
Cheers & hth,
Templates are the likely solution.
Its had to say without seeing more detail, but I note that you say "the function is really long with a lot of repeating code".
You can have:
a single function template
a refactor into a class template,
with the non type specific code in
base class methods might work well
a collection of function some of
which are templated with the
top-level function being templated
a top level templated function with
overloading of some of the
sub-routines.
Note you also use templating to map from the enum to the type:
enum meh { I_WANT_A_INT = 50001, I_WANT_A_FLOAT, I_WANT_A_DOUBLE };
template<meh = I_WANT_A_DOUBLE>
struct TriggerType
{
typedef double Type;
};
template<>
struct TriggerType<I_WANT_A_INT>
{
typedef int Type;
};
template<>
struct TriggerType<I_WANT_A_FLOAT>
{
typedef float Type;
};
template<class T> void setValue(T& t);
template<> void setValue<double>(double& t) { t = 11;}
template<> void setValue<int>(int& t) { t = 10;}
template<> void setValue<float>(float& t) { t = 10.111f;}
template<class T>
bool fooTyped()
{
T trigger;
setValue(trigger);
trigger *= 5;
std::cout << trigger << std::endl;
return true;
}
bool foo( meh triggerType )
{
bool ret = false;
switch ( triggerType )
{
case I_WANT_A_INT:
{
ret = fooTyped<TriggerType<I_WANT_A_INT>::Type>(); ;
}
break;
case I_WANT_A_FLOAT:
{
ret = fooTyped<TriggerType<I_WANT_A_FLOAT>::Type>(); ;
}
break;
default:
{
ret = fooTyped<TriggerType<I_WANT_A_DOUBLE>::Type>(); ;
}
break;
}
return ret;
}
void test ()
{
foo(I_WANT_A_INT);
foo(I_WANT_A_FLOAT);
foo((meh)63);
}
Note the dispatch on the enum mapping to the type; we need this explicit boiler plate because we can't use a run time value to instantiate the template.

Does C++ have "with" keyword like Pascal?

with keyword in Pascal can be use to quick access the field of a record.
Anybody knows if C++ has anything similar to that?
Ex:
I have a pointer with many fields and i don't want to type like this:
if (pointer->field1) && (pointer->field2) && ... (pointer->fieldn)
what I really want is something like this in C++:
with (pointer)
{
if (field1) && (field2) && .......(fieldn)
}
Probably the closest you can get is this: (this is just an academic exercise. Of course, you can't use any local variables in the body of these artificial with blocks!)
struct Bar {
int field;
};
void foo( Bar &b ) {
struct withbar : Bar { void operator()() {
cerr << field << endl;
}}; static_cast<withbar&>(b)();
}
Or, a bit more demonically,
#define WITH(T) do { struct WITH : T { void operator()() {
#define ENDWITH(X) }}; static_cast<WITH&>((X))(); } while(0)
struct Bar {
int field;
};
void foo( Bar &b ) {
if ( 1+1 == 2 )
WITH( Bar )
cerr << field << endl;
ENDWITH( b );
}
or in C++0x
#define WITH(X) do { auto P = &X; \
struct WITH : typename decay< decltype(X) >::type { void operator()() {
#define ENDWITH }}; static_cast<WITH&>((*P))(); } while(0)
WITH( b )
cerr << field << endl;
ENDWITH;
no there is no such keyword.
I like to use:
#define BEGIN_WITH(x) { \
auto &_ = x;
#define END_WITH() }
Example:
BEGIN_WITH(MyStructABC)
_.a = 1;
_.b = 2;
_.c = 3;
END_WITH()
In C++, you can put code in a method of the class being reference by pointer. There you can directly reference the members without using the pointer. Make it inline and you pretty much get what you want.
Even though I program mostly in Delphi which has a with keyword (since Delphi is a Pascal derivative), I don't use with. As others have said: it saves a bit on typing, but reading is made harder.
In a case like the code below it might be tempting to use with:
cxGrid.DBTableView.ViewData.Records.FieldByName('foo').Value = 1;
cxGrid.DBTableView.ViewData.Records.FieldByName('bar').Value = 2;
cxGrid.DBTableView.ViewData.Records.FieldByName('baz').Value = 3;
Using with this looks like this
with cxGrid.DBTableView.ViewData.Records do
begin
FieldByName('foo').Value = 1;
FieldByName('bar').Value = 2;
FieldByName('baz').Value = 3;
end;
I prefer to use a different technique by introducing an extra variable pointing to the same thing with would be pointing to. Like this:
var lRecords: TDataSet;
lRecords := cxGrid.DBTableView.ViewData.Records;
lRecords.FieldByName('foo').Value = 1;
lRecords.FieldByName('bar').Value = 2;
lRecords.FieldByName('baz').Value = 3;
This way there is no ambiguity, you save a bit on typing and the intent of the code is clearer than using with
No, C++ does not have any such keyword.
The closest you can get is method chaining:
myObj->setX(x)
->setY(y)
->setZ(z)
for setting multiple fields and using for namespaces.
C++ does not have a feature like that. And many consider "WITH" in Pascal to be a problem because it can make the code ambiguous and hard to read, for example it hard to know if field1 is a member of pointer or a local variable or something else. Pascal also allows multiple with-variables such as "With Var1,Var2" which makes it even harder.
with (OBJECT) {CODE}
There is no such thing in C++.
You can put CODE as is into a method of OBJECT, but it is not always desirable.
With C++11 you can get quite close by creating alias with short name for OBJECT.
For example code given in question it will look like so:
{
auto &_ = *pointer;
if (_.field1 && ... && _.fieldn) {...}
}
(The surrounding curly braces are used to limit visibility of alias _ )
If you use some field very often you can alias it directly:
auto &field = pointer->field;
// Even shorter alias:
auto &_ = pointer->busy_field;
No, there is no with keyword in C/C++.
But you can add it with some preprocessor code:
/* Copyright (C) 2018 Piotr Henryk Dabrowski, Creative Commons CC-BY 3.0 */
#define __M2(zero, a1, a2, macro, ...) macro
#define __with2(object, as) \
for (typeof(object) &as = (object), *__i = 0; __i < (void*)1; ++__i)
#define __with1(object) __with2(object, it)
#define with(...) \
__M2(0, ##__VA_ARGS__, __with2(__VA_ARGS__), __with1(__VA_ARGS__))
Usage:
with (someVeryLongObjectNameOrGetterResultOrWhatever) {
if (it)
it->...
...
}
with (someVeryLongObjectNameOrGetterResultOrWhatever, myObject) {
if (myObject)
myObject->...
...
}
Simplified unoverloaded definitions (choose one):
unnamed (Kotlin style it):
#define with(object) \
for (typeof(object) &it = (object), *__i = 0; __i < (void*)1; ++__i)
named:
#define with(object, as) \
for (typeof(object) &as = (object), *__i = 0; __i < (void*)1; ++__i)
Of course the for loop always has only a single pass and will be optimized out by the compiler.
First I've heard that anybody doesn't like 'with'. The rules are perfectly straightforward, no different from what happens inside a class in C++ or Java. And don't overlook that it can trigger a significant compiler optimization.
The following approach relies on Boost. If your compiler supports C++0x's auto then you can use that and get rid of the Boost dependence.
Disclaimer: please don't do this in any code that must be maintained or read by someone else (or even by yourself in a few months):
#define WITH(src_var) \
if(int cnt_ = 1) \
for(BOOST_AUTO(const & _, src_var); cnt_; --cnt_)
int main()
{
std::string str = "foo";
// Multiple statement block
WITH(str)
{
int i = _.length();
std::cout << i << "\n";
}
// Single statement block
WITH(str)
std::cout << _ << "\n";
// Nesting
WITH(str)
{
std::string another("bar");
WITH(another)
assert(_ == "bar");
}
}
Having written numerous parsers, this seems like a dead simple list look up for the named object, either static or dynamic. Further, I have never seen a situation where the compiler did not correctly identify the missing object and type, so all those lame excuses for not allowing a WITH ...ENDWITH construction would seem to be a lot of hooey. For the rest of us prone to long object names one workaround is to create simple defines. Couldn't resist, suppose I have:
#include<something>
typedef int headache;
class grits{
public:
void corn(void);
void cattle(void);
void hay(void);}; //insert function defs here
void grits::grits(void)(printf("Welcome to Farm-o-mania 2012\n");};
#define m mylittlepiggy_from_under_the_backporch.
headache main(){
grits mylittlepiggy_from_under_the_backporch;
m corn(); //works in GCC
m cattle();
m hay();
return headache;
#include <iostream>
using namespace std;
template <typename T>
struct with_iter {
with_iter( T &val ) : p(&val) {}
inline T* begin() { return p; }
inline T* end() { return p+1; }
T *p;
};
#define with( N, I ) for( auto &N : with_iter<decltype(I)>(I) )
int main() {
with( out , cout ) {
out << "Hello world!" << endl;
}
return 0;
}
Nuf said ...
I can see one instance where 'with' is actually useful.
In methods for recursive data structures, you often have the case:
void A::method()
{
for (A* node = this; node; node = node->next) {
abc(node->value1);
def(value2); // -- oops should have been node->value2
xyz(node->value3);
}
}
errors caused by typos like this are very hard to find.
With 'with' you could write
void A::method()
{
for (A* node = this; node; node = node->next) with (node) {
abc(value1);
def(value2);
xyz(value3);
}
}
This probably doesn't outweight all the other negatives mentioned for 'with', but just as an interesting info...
Maybe you can:
auto p = *pointer;
if (p.field1) && (p.field2) && ... (p.fieldn)
Or create a small program that will understand with statements in C++ and translate them to some form of a valid C++.
I too came from the Pascal world..... .....and I also LOVE Python's use of with (basically having an automatic try/finally):
with open(filename, "r") as file:
for line in file:
if line.startswith("something"):
do_more()
That acts like a smart ptr object. It does not go into the block if the open failed; and when leaving the block, the file if closed.
Here is a sample very close to Pascal while also supporting Python's usage (assuming you have a smart object with destructor cleanup); You need newer C++ standard compilers for it to work.
// Old way
cxGrid_s cxGrid{};
cxGrid.DBTableView.ViewData.Records.FieldByName.value["foo"] = 1;
cxGrid.DBTableView.ViewData.Records.FieldByName.value["bar"] = 2;
cxGrid.DBTableView.ViewData.Records.FieldByName.value["baz"] = 3;
// New Way - FieldByName will now be directly accessible.
// the `;true` is only needed if the call does not return bool or pointer type
if (auto FieldByName = cxGrid.DBTableView.ViewData.Records.FieldByName; true)
{
FieldByName.fn1 = 0;
FieldByName.fn2 = 3;
FieldByName.value["foo"] = 1;
FieldByName.value["bar"] = 2;
FieldByName.value["baz"] = 3;
}
And if you want even closer:
#define with if
with (auto FieldByName = cxGrid.DBTableView.ViewData.Records.FieldByName; true)
// Similar to the Python example
with (smartFile sf("c:\\file.txt"); sf)
{
fwrite("...", 1, 3, *sf);
}
// Usage with a smart pointer
with (std::unique_ptr<class_name> p = std::make_unique<class_name>())
{
p->DoSomethingAmazing();
// p will be released and cleaned up upon exiting the scope
}
The (quick and dirty) supporting code for this example:
#include <map>
#include <string>
struct cxGrid_s {
int g1, g2;
struct DBTableView_s {
int tv1, tv2;
struct ViewData_s {
int vd1, vd2;
struct Records_s {
int r1, r2;
struct FieldByName_s{
int fn1, fn2;
std::map<std::string, int> value;
} FieldByName;
} Records;
} ViewData;
} DBTableView;
};
class smartFile
{
public:
FILE* f{nullptr};
smartFile() = delete;
smartFile(std::string fn) { f = fopen(fn.c_str(), "w"); }
~smartFile() { if (f) fclose(f); f = nullptr; }
FILE* operator*() { return f; }
FILE& operator->() { return *f; }
operator bool() const { return f != nullptr; }
};
I was lamenting to PotatoSwatter (currently accepted answer) that I could not access variables declared in the enclosing scope with that solution.
I tried to post this in a comment response to PotatoSwatter, but it's better as a whole post. It's all a bit over the top, but the syntax sugar is pretty nice!
#define WITH_SIG float x, float y, float z
#define WITH_ARG x, y, z
#define WITH(T,s) do { struct WITH : T { void operator()(s) {
#define ENDWITH(X,s) }}; static_cast<WITH&>((X))(s); } while(0)
class MyClass {
Vector memberVector;
static void myFunction(MyClass* self, WITH_SIG) {
WITH(MyClass, WITH_SIG)
memberVector = Vector(x,y,z);
ENDWITH(*self, WITH_ARG);
}
}
A simple way to do this is as follows
class MyClass
{
int& m_x;
public MyClass(int& x)
{
m_x = x;
m_x++;
}
~MyClass()
{
m_x--;
}
}
int main():
{
x = 0;
{
MyClass(x) // x == 1 whilst in this scope
}
}
I've been writing python all day long and just scrapped this down before anyone takes me to the cleaners. In a larger program this is an example of how to keep a reliable count for something.

Building a call table to template functions in C++

I have a template function where the template parameter is an integer. In my program I need to call the function with a small integer that is determined at run time. By hand I can make a table, for example:
void (*f_table[3])(void) = {f<0>,f<1>,f<2>};
and call my function with
f_table[i]();
Now, the question is if there is some automatic way to build this table to arbitrary order. The best I can come up with is to use a macro
#define TEMPLATE_TAB(n) {n<0>,n<1>,n<2>}
which at leasts avoids repeating the function name over and over (my real functions have longer names than "f"). However, the maximum allowed order is still hard coded. Ideally the table size should only be determined by a single parameter in the code. Would it be possible to solve this problem using templates?
It can be done by 'recursive' dispatching: a template function can check if it's runtime argument matches it's template argument, and return the target function with the template argument.
#include <iostream>
template< int i > int tdispatch() { return i; }
// metaprogramming to generate runtime dispatcher of
// required size:
template< int i > int r_dispatch( int ai ) {
if( ai == i ) {
return tdispatch< i > ();
} else {
return r_dispatch< i-1 >( ai );
}
}
template<> int r_dispatch<-1>( int ){ return -1; }
// non-metaprogramming wrapper
int dispatch( int i ) { return r_dispatch<100>(i); }
int main() {
std::cout << dispatch( 10 );
return 0;
}
You can create a template that initializes a lookup table by using recursion; then you can call the i-th function by looking up the function in the table:
#include <iostream>
// recursive template function to fill up dispatch table
template< int i > bool dispatch_init( fpointer* pTable ) {
pTable[ i ] = &function<i>;
return dispatch_init< i - 1 >( pTable );
}
// edge case of recursion
template<> bool dispatch_init<-1>() { return true; }
// call the recursive function
const bool initialized = dispatch_init< _countof(ftable) >( ftable );
// the template function to be dispatched
template< int i > void function() { std::cout << i; }
// dispatch functionality: a table and a function
typedef void (*fpointer)();
fpointer ftable[100];
void dispatch( int i ){ return (ftable[i])(); }
int main() {
dispatch( 10 );
}
[Proven wrong: I don't think that can be done purely with templates.]
Take a look at the boost preprocessor library.
Following xtofl I decided to go with the following macro/template solution shown below. I needed the macro because I want to build these dispatch tables for many functions, and I cannot see how to do that with one single template function.
#include <iostream>
using namespace std;
#define MAX_ORDER 8
#define DISPATCH_TABLE(table,fpointer,function,N) \
template< int i > fpointer *function##dispatch_init(fpointer function_table[]) \
{ \
function_table[i] = function<i>; \
return function##dispatch_init< i - 1 >(function_table); \
} \
template<> fpointer *function##dispatch_init<-1>(fpointer function_table[]) \
{ \
return function_table; \
} \
const fpointer *table = function##dispatch_init<N>(new fpointer[N])
typedef void (*fpointer)(void);
template<int N>
void printN(void)
{
cout << N << endl;
}
DISPATCH_TABLE(printN_table, fpointer, printN, MAX_ORDER);
int main(void)
{
for (int i = 0; i < MAX_ORDER; i++)
printN_table[i]();
return 0;
}