jeudi 29 octobre 2015

Is there a simpler way to get to a member of a class wrapped in a smart pointer?

Apologies for the cryptic title. Suppose this definition:

struct TestNode {
    using CostType = double;
};

I would like to be able to define a class template like this:

template <typename NodeP,
          typename MyPolicy = /* CostType of the node type corresponding to NodeP */ >
struct TT {
};

In the above definition, NodeP can be either a simple or a smart pointer to a class that defines CostType, such as TestNode. The problem: how can one specify a default value for the MyPolicy template parameter to be the CostType of the node type corresponding to NodeP?

Here is my solution so far:

// like std::remove_pointer, but works with smart pointers as well
template <typename PT> struct my_remove_pointer {
    using type = typename
        std::remove_reference< decltype( *((PT)nullptr) ) >::type;
};

struct TestNode {
    using CostType = double;
};

template <typename NodeP,
          typename MyPolicy = typename my_remove_pointer<NodeP>::type::CostType>
struct TT {
};

Is there a simpler approach to this problem? In particular, am I missing a standard library facility that could make the solution simpler?

C++ library to create Ppt/ pptx document

I am new to c++ language. i am looking for an open source c++ library (cross platform) to create and manage the ppt / pptx document.

Please suggest me a good c++ library for presentation.

Force a compile time error in a template specialization

I recently started to learn modern template metaprogramming and I wrote myself an index_of function for types.

template<std::size_t Index, class C, class A> struct mp_index_of_impl{};
template<std::size_t Index, class C,template<class...> class A,class ...Ts>
struct mp_index_of_impl<Index,C,A<C,Ts...>>{
    using type = std::integral_constant<std::size_t,Index>;
};
template<std::size_t Index, class C,template<class...> class A,class ...Ts,class T1>
struct mp_index_of_impl<Index,C,A<T1,Ts...>>{
    using type = typename mp_index_of_impl<Index + 1,C,A<Ts...>>::type;
};
template<std::size_t Index, class C,template<class...> class A> struct mp_index_of_impl<Index,C,A<>>{
    //static_assert(false,"Does not contain type");
    using type = std::integral_constant<std::size_t,0>;
};

The problem is my last specialization

template<std::size_t Index, class C,template<class...> class A> 
struct mp_index_of_impl<Index,C,A<>>{
      //throw a compile error here
};

I tried to use static_assert like this

template<std::size_t Index, class C,template<class...> class A> struct mp_index_of_impl<Index,C,A<>>{
    static_assert(false,"Does not contain type");
};

But this will throw a compile error every time, even if it is not matched.

I want to throw a compile error with a custom error message if this template specialization is matched. How would I do this?

cannot convert parameter 1 from 'const boost::shared_mutex' to 'const boost::shared_lock

I am just trying to implement this answer about mutexes with over 100 upvotes. All I did was copy paste the code, so that my class reads (simplified) like this:

mymutexclass.h

class MyMutexClass {
public:
    void write( uint32_t id, const std::string &str );
    std::string read( uint32_t id ) const;

private:
    boost::shared_mutex _access;
    std::map<uint32_t, std::string> strings;
};

mymutexclass.cpp

void MyMutexClass::write( uint32_t id, const std::string &str ) {
    boost::unique_lock< boost::shared_mutex > lock(_access);
    strings[id] = name;
}
std::string MyMutexClass::read( const uint32_t id ) const {
    boost::shared_lock< boost::shared_mutex > lock(_access); // ERROR HERE
    if( strings.count( id )>0) 
        return strings.at(id);
    else
        return "No value.";
}

And I get an error, only for the read mutex line:

error C2664: 'boost::shared_lock<Mutex>::shared_lock(const boost::shared_lock<Mutex> &)' : cannot convert parameter 1 from 'const boost::shared_mutex' to 'const boost::shared_lock<Mutex> &'   D:\... path ...\mymutexclass.cpp

I am completely lost in the error - what's the difference between the types it complains about? I mean these, from the error:

  • from const boost::shared_mutex
  • to const boost::shared_lock<Mutex> &

And what am I doing wrong? That linked answer was upvoted 100 times, so I guess it's really likely to be correct.

Default-insertion, C++11, and libstdc++

The current working draft of the C++ Standard (http://ift.tt/1M1jxWT) introduces so-called default-insertion [§23.2.1(15.2)]. The vector::resize(sz) then appends sz - size() default-inserted elements to the sequence in case that sz > size() (effectively, this calls the construct() member function of the corresponding allocator for appended vector elements).

According to the C++11 Standard ISO/IEC 14882:2011(E), vector::resize(sz) appends sz - size() value-initialized elements to the sequence in such a case (allocator is not used at all).

However, the GNU Standard C++ Library v3 (libstdc++) implements default-insertion already for C++11 via the preprocessor branch #if __cplusplus >= 201103L (observed in libstdc++ 3.4.20).

I really appreciate the default-insertion concept, but doesn't it mean that libstdc++ breaks the C++11 compatibility?

When are 'auto' and 'decltype' evaluated?

When are auto and decltype (for lack of a better word) "evaluated"? At runtime, or when the code is compiled?

If it is the former, does using them have any noticeable performance penalty compared to hard-coding the variable type?

Suffix ($´) in c++ regex_replace doesn't work

According to c++ regex_replace specification, is supposed to specify the suffix of the match. But it doesn't work:

#include <iostream>
#include <string>
#include <regex>
#include <iterator>

int main ()
{
  std::string s ("there is a subsequence in the string\n");
  std::regex e ("\\b(a )(subsequence)(.*)");
  // with flags:
  std::cout << std::regex_replace (s,e,"$´1digit$03",std::regex_constants::format_default);
  std::cout << std::endl;

  return 0;
}

Output:

there is $´1digit in the string

Instead of the suffix, it prints literally. How can I make this work?

N.B: I couldn't find this ´ character on my keyboard (copied from the regex_replace specification page from cplusplus.com)