mardi 1 septembre 2015

Defining trait in parent class

I have a hierarchy of "codecs" to encode/decode various things to a binary stream. They all inherit from a parent Codec class, on which I'd like to define a few types, to use in the subclasses, as in:

class Codec {
  public:
    typedef char* pointer;
    ...
};

Alas, the type pointer seems to be unknown in the subclasses of Codec. Is there any way I could it make visible in the subclasses?

How that FOR loop line work in c++?

I found code that used for loop like below :

//// Code
for(int i = 0; i < MAX; i++);
//// Code

i dont understand what that do as there is ; in the end and no {} for starting the loop. Did anyone have any idea how that work in that case ? Thanks

How to use type traits to define a partially abstract template base class?

I'm working on the following idea:

There exists a generally abstract templated base class with mutiple template parameters. This class defines a contract guaranteeing the presence of certain methods i.e. a method getMax(). This method among others is generally purely virtual. Except there are special cases in which a sensible implementation can be given without the need to implement it manually every time in a derived class. So basically what I'm trying to achive is to (partially) implement the contracted methods already inside the abstract base class if the template arguments allow this.

I made a small example to illustrate the idea. (Note: The example is not perfect, for instance the implementation for std::string is very special and already implicitly forces TSize to be std::size_t)

#ifndef ABSTRACTBASE_H
#define ABSTRACTBASE_H

#include <type_traits>
#include <string>
#include <limits>

template <typename TSize, typename TVal1, typename TVal2>
class AbstractBase
{
    public:
        AbstractBase(){};
        virtual ~AbstractBase() {};
        virtual TSize getMax() const = 0; // <-- getMax should be generally 
                                          //     purely virtual.

    private:
        TVal1 value1;
        TVal2 value2;
};

//except when TVal1 is an arithmetic type in that case the following definition 
//shall become active.
template <typename TSize, 
          typename TVal1, 
          typename TVal2, 
          typename = typename std::enable_if<std::is_arithmetic<TVal1>::value, TSize>::type>
TSize AbstractBase<TSize, TVal1, TVal2>::getMax()
{
    return std::numeric_limits<TVal1>::max();
}

//... or when TVal1 is a string where this defintion makes sense
template <typename TSize, 
          typename TVal1, 
          typename TVal2, 
          typename = typename std::enable_if<std::is_same<TVal1, std::string>::value, TSize>::type>
TSize AbstractBase<TSize, TVal1, TVal2>::getMax()
{
    return value1.max_size();
}

//... in all other cases the getMax() method shall stay purely virtual and an 
//appropriate definition must be implemented inside a derived class

#endif //ABSTRACTBASE_H


#include "AbstractBase.h"
#include <string>
#include <iostream>

int main()
{
    AbstractBase<int, int, int> arthBase();
    AbstractBase<std::size_t, std::string, long> alphaBase();

    std::cout << arthBase.getMax() << std::endl;
    std::cout << alphaBase.getMax() << std::endl;
}

So I guess what is missing here is a method to actually also alter the declaration ov getMax() as virtual, though im not really sure if/how this is possible using type_traits.

Side note: I haven't worked with type traits very much yet. I know about the SFINAE principle behind it, which basically states that if the substitution for a template parameter fails the following code will be excluded from compilation rather than causing an error. What I haven't found out if the type_trait argument responsible for enabling/disabling the method has to be merged into the class template argument list like I did above, or if it is legal/possible to provide the type trait arguments in a seperate template argument list. In this case I guess it is impossible because the enable_if statement tests the classes template arguments which have to be declared/valid in this context.

Just in case you use really sophisticated type trait magic a more elaborate comment on that part is greatly appreciated.

run time error with respect to execution of randomized quicksort

i'm trying to implement randomized version of quicksort.i have successfully used the normal version of quicksort,but now the g++ compiler says floating point exception (core dumped). How do i proceed???

#include<bits/stdc++.h>
using namespace std;
void qsort(int* a,int start,int end);

int part(int*a,int start, int end);

int main()
{
int i,n;
cout<<"enter no of elements...."<<endl;
cin>>n;
int a[n];
cout<<"enter the elements to be sorted"<<endl;
for(i=0;i<n;i++)
cin>>a[i];
int start=0;
qsort(a,start,n-1);
cout<<"the list is..";
for(i=0;i<n;i++)
cout<<a[i]<<' ';
return 0;
}

void qsort(int* a,int start,int end)
{
if(end>start)
{
int pi=part(a,start,end);
qsort(a,start,pi-1);
qsort(a,pi+1,end);
}
}

int part(int*a,int start, int end)
{
int pi,pivot,k;



int i=start+rand()%(start+end-1);
pi=start;       
pivot=a[i];
int j,t;

for(j=start;j<end;j++)
{
if(a[j]<=pivot)
{
t=a[j];
a[j]=a[pi];
a[pi]=t;
pi++;
}
}
t=a[i];
a[i]=a[pi];
a[pi]=t;

return pi;
}

Ambiguous call for overloaded function templates - even if one is more specialized?

Consider the following:

#include <iostream>
#include <utility>

template <size_t N>
using size_ = std::integral_constant<size_t, N>; 

template <size_t From>
void f(size_<From>, size_<From+1> ) // (1)
{ }

template <size_t From, size_t To>   // (2)
void f(size_<From>, size_<To> )
{ }

int main()
{
    f(size_<0>{}, size_<1>{});
}

Both gcc and clang report the call as ambiguous. Why? Isn't (1) more specialized than (2)?

Note: I know this is easily fixable with an extra enable_if_t<(To > From+1)> thrown into (2), but I wouldn't have thought I needed to do that.

Type mismatch when passing member function pointer to a function that takes MFP with variadic arguments

I have a template function that takes pointer to a member function of any type with any amount of arguments (but enforces some rules - it has to be void and the last argument has to be a pointer):

class Foo {
public:
    Foo() {}

    template<typename T, typename Out, typename ... In>
    void foo(T *obj, void(T::*func)(In ..., Out*)) {
        ...
    }
    ...
};

When I try to invoke the function, I get a type mismatch error:

class Bar {
public:
    Bar() {}
    void bar(int in, bool *out) {
        ...
    }
};

int main()
{
   Foo foo;
   Bar bar;

   foo.foo<Bar, bool, int>(&bar, &Bar::bar);
   ...
}

Error:

test.cpp: In function 'int main()':
test.cpp:41:44: error: no matching function to call to 'Foo::foo(Bar*, void (Bar::*)(int, bool*))'
    foo.foo<Bar, bool, int>(&bar, &Bar::bar);
                                           ^
test.cpp:24:10: note: candidate: template<class T, class Out, class ... In> void Foo::foo(T*, void (T::*)(In ..., Out*))
    void foo(T *obj, void(T::*func)(In ..., Out*))
         ^
test.cpp:24:10: note    template argument deduction/substitution failed:
test.cpp:41:44: note    mismatched types 'bool*' and 'int'
    foo.foo<Bar, bool, int>(&bar, &Bar::bar);
                                           ^

The interesting things is that when I make In a simple type instead of parameter pack then it compiles and works correctly. This seems to me like if the compiler did not expand the pack somewhere and try to match the second argument (bool*) to the first argument (int) instead of the second one.

std::shared_future operator= thread safety/ atomic?

General question: Is std::shared_future::operator= atomic?

For example

struct object {
    object() {
        sf = std::async(std::launch::async, &async_func).share(); 
    }
    void change(){
        sf = std::async(std::launch::async, &other_async_func).share();
    }
    void read(){
        while (true){ sf.get(); }
    }
    std::shared_future<int> sf;
};

Question Part 1 Is it ok to call std::shared_future::operator= while the left e.g. old shared_future has not been waited on/asynchronous provider still running? Like in object::change().

Question Part 2 Is it ok to call std::shared_future::operator= while other asynchronous return objects / threads that are concurrent calling std::shared_future.get()? Like in object::read()?

After reading of C++11 draft N3485 §30.6.7:12

shared_future& operator=(shared_future&& rhs) noexcept; 12 Effects:

— releases any shared state (30.6.4);

— move assigns the contents of rhs to *this

Question Part 1 depends solely on releasing a shared state e.g. after reading of §30.6.4, destroying a shared state so I guess that means, Part 1 should be true, but I'm not sure.

Question Part 2 seems to be false, because this are 2 steps and I neither don't know if the move part is atomic nor if what happens if the shared state is destroyed while other threads are in shared_future::get()