Visual C++ "For Each" Portability

Visual c++ for each portability

For each is not standard C or C++ syntax. If you want to be able to compile this code in gcc or g++, you will need to create an iterator and use a standard for loop.

QuantumPete

[edit]
This seems to be a new feature introduced into MS Visual C++, so this is definitely not portable. Ref: http://msdn.microsoft.com/en-us/library/xey702bw%28VS.80%29.aspx [/edit]

Is for each Microsoft specific?

The current standard draft does not include the for each ( auto i in v ) syntax, only the for ( auto i : myints ), so yes, it is just an extension.

Portability of Native C++ properties

This is something similar to what you are asking and is (I hope) standard C++...

#include <iostream>

template<typename C, typename T, T (C::*getter)(), void (C::*setter)(const T&)>
struct Property
{
C *instance;

Property(C *instance)
: instance(instance)
{
}

operator T () const
{
return (instance->*getter)();
}

Property& operator=(const T& value)
{
(instance->*setter)(value);
return *this;
}

template<typename C2, typename T2,
T2 (C2::*getter2)(), void (C2::*setter2)(const T2&)>
Property& operator=(const Property<C2, T2, getter2, setter2>& other)
{
return *this = (other.instance->*getter2)();
}

Property& operator=(const Property& other)
{
return *this = (other.instance->*getter)();
}
};

//////////////////////////////////////////////////////////////////////////

struct Foo
{
int x_, y_;

void setX(const int& x) { x_ = x; std::cout << "x new value is " << x << "\n"; }
int getX() { std::cout << "reading x_\n"; return x_; }

void setY(const int& y) { y_ = y; std::cout << "y new value is " << y << "\n"; }
int getY() { std::cout << "reading y_\n"; return y_; }

Property<Foo, int, &Foo::getX, &Foo::setX> x;
Property<Foo, int, &Foo::getY, &Foo::setY> y;

Foo(int x0, int y0)
: x_(x0), y_(y0), x(this), y(this)
{
}
};

int square(int x)
{
return x*x;
}

int main(int argc, const char *argv[])
{
Foo foo(10, 20);
Foo foo2(100, 200);
int x = foo.x; std::cout << x << "\n";
int y = foo.y; std::cout << y << "\n";
foo.x = 42; std::cout << "assigned!\n";
x = foo.x; std::cout << x << "\n";
std::cout << "same instance prop/prop assign!\n";
foo.x = foo.y;
std::cout << "different instances prop/prop assign\n";
foo.x = foo2.x;
std::cout << "calling a function accepting an int parameter\n";
std::cout << "square(" << foo.x << ") = " << square(foo.x) << "\n";
return 0;
}

As you can see from main the usage is transparent as long as you are assigning values of type T (here int) or implicitly convertible to T to properties and as long you are converting them back to T values on reading.

Behavior will be different however if you for example pass foo.x to a template function because the type of foo.x is not int but Property<Foo, int, ...> instead.

You can also have problems with non-template functions... calling a function accepting a T value will work fine, however a T& parameter is for example going to be a problem because basically the function is asking a variable to access directly using the address. For the same reason you cannot pass of course the address of a property to a function accepting a T* parameter.

Is for each statement legal in C++11

From MSDN:

Iterates through an array or collection. This non-standard keyword is available in both C++/CLI and native C++ projects. However, its use is not recommended. Consider using a standard Range-based for Statement (C++) instead.

How to make Visual Studio 2017 C++ project more portable between computers?

As @gaurav says, the way to deal with this in Visual Studio is with property sheets. It's unfortunate that this term is used for two different things in VS, but I guess they just ran out of names (spoiler alert).

These are very powerful, once you learn how they work, and they're just what you need here because they let you define macros, and these macros can in turn be used in the rest of your project to refer to the (volatile) location of your various libraries. This is a trick that everyone who uses VS should know, but it seems that a lot of people don't.

I don't think it's worth me trying to walk you through the mechanics of setting one up here because Microsoft already document it in the Visual Studio help file. Suffice to say, you do it in the Property Manager, that should help you track down the relevant information.

There is also an excellent blog post here which I recommend you read before you do anything else:

http://www.dorodnic.com/blog/2014/03/20/visual-studio-macros/

It's also on Wayback Machine here:

https://web.archive.org/web/20171203113027/http://www.dorodnic.com/blog/2014/03/20/visual-studio-macros/

OK, so now we know how to define a macro, what can we do with it?

Well, that's actually the easy part. If we have a macro called, say, FOO, then wherever we want to expand that macro in some project setting or other we can just use $(FOO). There's also a bunch of macros built into the IDE as listed here:

https://msdn.microsoft.com/en-us/library/c02as0cs.aspx

So, you, I imagine, will want to define macros for the include and lib directories for each of your external libraries and you can then use these to replace the hard-coded paths you are currently using in your project.

And that, I reckon, should sort you out, because the definitions of the macros themselves are stored in a separate file, external to your project file, and different users / build machines can use different files. IIRC, these have extension .props.

Also, you can define a macro in terms of another macro or macros, and that makes the job easier still.

So, who still thinks that Microsoft don't know how to create a build system? Visual Studio is a fantastic piece of software once you get used to it, there's just a bit of a learning curve.

va_copy -- porting to visual C++?

You should be able to get away with just doing a regular assignment:

va_list apcopy = ap;

It's technically non-portable and undefined behavior, but it will work with most compilers and architectures. In the x86 calling convention, va_lists are just pointers into the stack and are safe to copy.

Visual Studio 2015 = QtCreator 5 (c++) code portability

QtCreator isn't linux environment, it is a portable. If your project is Qt-based , you can install mingw version of Qt SDK, It includes Creator allows (mostly) to emulate use of its analog on linux platform.

Portability defined not by IDE, but by toolchain you use, compiler, libraries, make utility.

Those names you had listed are header files, not libraries.

ISO C++ contains list of header files that should be supported by compatible compiler. You can check them here:

http://en.cppreference.com/w/cpp/header

thus math.h is not a C++ header, replace it with <cmath>, strsafe is Microsoft header without any analog on other platforms, its usage should be replaced.

If project meant to be built on different platforms and it is not possible to implement all its functionality in same way on both, you should consider usage of toolchain that is able to configure your project for particular platform. E.g., cmake.

Porting permutation function from Python to C++

I decided not to go to sleep tonight and find the answer by adding verbose debugging to both versions of the algorithm and studying how they differ.

The problem is this section of code:

        for (auto p : permute(list, nextFixable, num, begin + 1, end)) {
__yield_value p;
swap(list[begin], list[i]);
swap(num[begin], num[i]);
nextFixable[list[i]]--;
}

To match the python it should be:

        for (auto p : permute(list, nextFixable, num, begin + 1, end)) {
__yield_value p;
}
swap(list[begin], list[i]);
swap(num[begin], num[i]);
nextFixable[list[i]]--;

Possibly when pasting the Python code into VS it helpfully lined everything up, and thanks to Python's convenient lack of braces, when comparing the code again this went unnoticed.

This triggered a second issue where nextFixable[whatever] would decrement below 0 on an unsigned integer and overflow - but that's what gave it away.

(However as noted in comments I have taken on board the suggestion to use std:next_permutation in a do-while loop in conjunction with a std:sort beforehand. That solution has in a simple experiment proven to be about 5-6 times faster than this algorithm.)

Including a header file in VS 2017 for portable projects (C++)

You must use relative path. Do this:

1- Create a new subfolder in your solution. Let's call it include:

Sample Image
2- Put your shared headers in this subfolder. Example : myCommonFunctions.h

Sample Image

First solution: Use relative include path (see ../ at begining)

#include "../include/myCommonFunctions.h"  

Second solution: Use relative path in Addtional include directories (see ../ at begining)

Sample Image

Now, you can write :

#include "myCommonFunctions.h"  

By doing this, you don't depend from an absolute path C:\\Projects\\MyProgram\\... and You will no longer need to copy files manually if you change computers



Related Topics



Leave a reply



Submit