mercredi 2 septembre 2015

Non-terminating recursive use of decltype

Compilation of the following code has problems due to infinite compile-time recursion. Clang 3.6.0 gives an error about recursive template instantiation depth, and doesn't terminate; while GCC 4.9.2 remains silent, and also doesn't terminate.

This is a simpler example than I was originally faced with, and certainly the second overload of bar could be given int as a return type; in this case, the first overload is chosen for the call to bar in main; as I'd originally hoped. Why does the application of decltype not resolve to the first overload, which is specialised for Foo?

The second (default) template parameter of Foo seems to hide more verbose messages regarding the recursion issue here. This would have been useful in the original context.

template <typename T, typename A = T>
struct Foo {};

template <typename T, typename A>
int bar(const Foo<T,A> &x) { return 0; }

template <typename T>
auto bar(const T &x)
 -> decltype(bar(Foo<T>{})){    
    return   bar(Foo<T>{});    
}

int main(int argc, char *argv[])
{
  Foo<char> f;    
  bar(f);

  return 0;
}

Convert long int* to long long int*

On my platform, both long int and long long int are the same (64 bits). I have a pointer to a long int and I want to convert it to a pointer to a long long int. The following code

static_cast<long long int*>(pointer);

is not allowed. What is the correct way to do that in C++11?

Move and Forward cases use

I followed this tutorial to start to understand the move semantics and rvalue references in C++11. At some point, he implements these two classes with the std::move in the move constructors explaining that

we pass the temporary to a move constructor, and it takes on new life in the new scope. In the context where the rvalue expression was evaluated, the temporary object really is over and done with. But in our constructor, the object has a name; it will be alive for the entire duration of our function. In other words, we might use the variable other more than once in the function, and the temporary object has a defined location that truly persists for the entire function. It's an lvalue in the true sense of the term locator value

class MetaData
{
public:
    MetaData(int size, const string& name)
        : _name(name)
        , _size(size)
    {}

    MetaData(const MetaData& other)
        : _name(other._name)
        , _size(other._size)
    {
        cout << "MetaData -- Copy Constructor" << endl;
    }

    MetaData(MetaData&& other)
        : _name(move(other._name))
        , _size(other._size)
    {
        cout << "MetaData -- Move Constructor" << endl;
    }

  ~MetaData()
  {
    _name.clear();
  }

    string getName() const { return _name; }
    int getSize() const { return _size; }

private:
    string _name;
    int _size;
};

class ArrayWrapper
{
public:
    ArrayWrapper()
        : _p_vals(new int[64])
        , _metadata(64, "ArrayWrapper")
    {}

    ArrayWrapper(int n)
        : _p_vals(new int[n])
        , _metadata(n, "ArrayWrapper")
    {}

    ArrayWrapper(ArrayWrapper&& other)
        : _p_vals(other._p_vals)
        , _metadata(move(other._metadata))
    {
        cout << "ArrayWrapper -- Move Constructor" << endl;
        other._p_vals = nullptr;
    }

    ArrayWrapper(const ArrayWrapper& other)
        : _p_vals(new int[other._metadata.getSize()])
        , _metadata(other._metadata)
    {
        cout << "ArrayWrapper -- Copy Constructor" << endl;
        for (int i = 0; i < _metadata.getSize(); ++i)
            _p_vals[i] = other._p_vals[i];
    }

    ~ArrayWrapper()
    {
        delete[] _p_vals;
    }

    int* getVals() const { return _p_vals; }
    MetaData getMeta() const { return _metadata; }

private:
    int* _p_vals;
    MetaData _metadata;
};

In the ArrayWrapper move constructor I tried to change std::move with std::forward<MetaData> and the code shows that if I call the ArrayWrapper move constructor this will call the MetaData move constructor, like the example with the std::move.

Of course if I don't use either std::move or std::forward the MetaData copy costructor will be called.

The question is, in this case, is there a difference between using std::move and std::forward? Why should I use one instead of the other?

Refactor multiple repeated functions differing only at the innermost scope

I'm trying to find a refactoring solution to the following scenario. I have many duplicated functions, each doing exactly the same thing except calling a different member function on a class instance available only at the inner-most scope.

struct MyObject
{
    void Function1() {};
    void Function2() {};
    void Function3() {};
    void Function4() {};
};

std::vector<MyObject *> objects;

void CommandHandler1()
    {
    if (true) // lots of preconditions
        {
        size_t id = 0;
        if (true) // lots of lookup code for id
            {
            MyObject *myObject = objects.at(id);
            myObject->Function1();
            }
        // refresh code
        }
    // cleanup code
    }

// another CommandHandler2, CommandHandler3, CommandHandler4, etc. doing the same thing but for a different member function.

I'd like to avoid this duplication of multiple CommandHandlerx because they're so very similar. What I've tried is to pass a std::function to work on any instance, because I can't bind to a specific instance. An answer to this question implies that the following mini-program should compile.

#include <functional>

void CommandHandler(std::function<void(MyObject *)> func)
{
    if (true) // lots of preconditions
        {
        size_t id = 0; 
        if (true) // lots of lookup code for id
            {
            MyObject *myObject = objects.at(id);
            func(myObject);
            }
        }
    // cleanup code
}

void MenuHandler(int chosen)
    {
    switch (chosen)
        {
        case 0: CommandHandler( &MyObject::Function1); break;
        case 1: CommandHandler( &MyObject::Function2); break;
        case 2: CommandHandler( &MyObject::Function3); break;
        case 3: CommandHandler( &MyObject::Function4); break;
        }
    }

int main()
{
    MyObject *obj1 = new MyObject;
    MyObject *obj2 = new MyObject;
    objects.push_back(obj1);
    objects.push_back(obj2);

    MenuHandler(1);

    delete obj1; delete obj2;
    return 0;
}

This unfortunately doesn't build. I presume because I'm not binding against a specific this pointer:

C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional(506): error C2664: 'void std::_Func_class<_Ret,MyObject *>::_Set(std::_Func_base<_Ret,MyObject *> *)' : cannot convert argument 1 from '_Myimpl *' to 'std::_Func_base<_Ret,MyObject *> *'

My question is either (1) am I doing something wrong with the above std::function attempt, or (2) is there any other pattern for refactoring this scenario?

CMake: C++11 not set with CXX_STANDARD

I want to compile a library using C++11. The library is a subproject. In its CMakeLists.txt I set the C++11 features with CXX_STANDARD and CXX_STANDARD_REQUIRED as seen here.

The cmake command it's executed without errors, but when I start the compilation I obtain errors related to C++11 features missing, like

In file included from /folder/OptionWidget.cpp:1:0:
/folder/OptionWidget.h:14:28: warning: defaulted and deleted functions only available with -std=c++0x or -std=gnu++0x [enabled by default]
/folder/OptionWidget.h:14:28: error: ‘virtual WTradeGui::OptionWidget::~OptionWidget()’ declared virtual cannot be defaulted in the class body
make[2]: *** [.../OptionWidget.cpp.o] Error 1

The error lies where I declare a default virtual destructor in header virtual ~OptionWidget() = default;

If I execute the command make VERBOSE=1 I can see that the C++11 flag is not set in compilation command:

 /usr/bin/c++   -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NO_DEBUG -DQT_WIDGETS_LIB -I/folder/wtradegui -I/folder/wtradegui -I/folder/wtrade/src -isystem /qt/include -isystem /qt/QtWidgets -isystem /qt/QtGui -isystem /qt/QtCore -isystem -fPIC -o CMakeFiles/http://ift.tt/1JB5dEM -c /folder/OptionWidget.cpp

I use Ubuntu 15.04 with cmake version 3.3.1 and gcc version 4.6.3.

The same project is built without problems under windows, using MinGW (sorry I don't remember the version, it's the one shipped with Qt 5.5.0 release).

What I must do in order to build the project in Linux?

This is the main CMakeList.txt

# In order to work following variables must be set
#
# QT_DIR: Path to Qt installation.

cmake_minimum_required (VERSION 3.1.0)

# Variables that should be set before execution
if (WIN32)
    set (QT_DIR "" CACHE PATH "Qt library path")
else (WIN32)
    set (QT_DIR "/usr/include" CACHE PATH "Qt library path")
endif (WIN32)

message ("Generating WPlot project")
message ("Setting QT_DIR To ${QT_DIR}")

add_subdirectory (wplot)
add_subdirectory (demo)

And this is the CMakeLists.txt inside wplot folder

# wPlot project

cmake_minimum_required (VERSION 3.1.0)

project (wplot)

set (major_version 0)
set (minor_version 0)
set (bugfix_version 1)
set (project_version ${major_version}.${minor_version}.${bugfix_version})
set (OUTPUT_DIR "build")
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/export/lib)
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/export/lib)
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/export/bin)
set (INCLUDE_EXPORT_DIRECTORY ${CMAKE_BINARY_DIR}/export/include/wplot)
set (CMAKE_DOC_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/export/doc)
set (CMAKE_PREFIX_PATH ${QT_DIR}/lib/cmake)
set (CMAKE_AUTOMOC ON)
set (CMAKE_INCLUDE_CURRENT_DIR ON)

message ("=== Generating WPlot ===")
message ("Setting QT_DIR To ${QT_DIR}")
message ("CMAKE_PREFIX_PATH set to ${CMAKE_PREFIX_PATH}")
find_package (Qt5Widgets REQUIRED)
include_directories (${CMAKE_SOURCE_DIR} ${Qt5Widgets_INCLUDE_DIRS})
file (GLOB_RECURSE WPLOT_SOURCES "*.cpp")
file (GLOB WPLOT_PUBLIC_HEADERS "*.h")
file (COPY ${WPLOT_PUBLIC_HEADERS} DESTINATION ${INCLUDE_EXPORT_DIRECTORY})

# Compile project
add_definitions(-DWPLOT_LIBRARY)
add_library (wplot SHARED ${WPLOT_SOURCES})
target_link_libraries(wplot ${Qt5Widgets_LIBRARIES})
set_target_properties(
  wplot
  PROPERTIES
    VERSION ${project_version}
    SOVERSION ${project_version}
)
set_property(TARGET wplot PROPERTY CXX_STANDARD 11)
set_property(TARGET wplot PROPERTY CXX_STANDARD_REQUIRED ON)

C++ Comparing Two Integer Values, one simple and one pointer

I have the following function in c++:

bool compareThem(int top_limit, int* maximum)
{
       if( top_limit >= maximum )
       {
            cout << "Error, maximum number shown be greater than top_limit.";
       }
}

I want a simple comparison between the integer and integer pointer, though, logically C++ cannot do it, since with == operator, int and int* are not of the same type. How should I then solve it?

Is std::atomic signal-safe?

I am working on a Linux app, which needs to be able to handle large bursts of signals. Although the signal handlers will run fast (I plan at most some thousands of cpu cycles), the signals will come in big bursts, and ideally I would completely disable signal masking (even not themselfes, see SA_NODEFER in sigaction).

Thus, I need to implement the signal handlers on a completely reentrant way. I think std::atomic would be an useful thing for the task, but I think, std::atomic was developed to handle thread-based race conditions, and not necessarily race problems coming from stacked on signal handlers.