English 中文(简体)
助推: 配对——复制NON-POD的物体,如POD型,返回
原标题:boost::aligned_storage copying NON-POD objects like a POD type on return

我有一个使用加固的班子:在物体内固定分配记忆,然后在稍后时间开始发射物体。 然而,一个试验方案中的坠毁似乎表明,停战者被召入初始物体,这是一个障碍:在这种情况下,我试图在功能呼吁之后归还物体。 然后,在返回地点,似乎只有数据被复制到新物体的转让上,如该物体是POD型。 这意味着,我下次试图接触被分配物体时,它没有发现存取错误。

更具体地说,我执行一个称为“静坐器”的班子:试图与波斯特紧密匹配的校长。 跟踪和规模跟踪,汇编固定能力。

我的测试方案教授如下:

  1. calls a function that adds a randomly filled std::set to a StaticVector
  2. returns it to a local variable
  3. the destructor is being called on the return, but for some reason the returned object isn t copying correctly
  4. when the local variable goes out of scope free gets called on uninitialized memory
  5. Crash

www.un.org/Depts/DGACM/index_spanish.htm 这一坠毁的起因是什么,我如何解决?

The full code and a convenient CMakeLists.txt file can be found at: https://github.com/ahundt/Boost.StaticVector

主 席:

// benchmark based on: http://cpp-next.com/archive/2010/10/howards-stl-move-semantics-benchmark/

#include "StaticVector.hpp"
#include <vector>
#include <iostream>
#include <time.h>
#include <set>
#include <algorithm>
#include <exception>

const unsigned N = 3;
extern bool some_test;

template<typename T>
T get_set(std::size_t)
{
    T s;
    for (std::size_t i = 0; i < N; ++i)
        while (!s.insert(std::rand()).second)
            ;
    if (some_test)
        return s;
    return T();
}

template<typename T>
T generate()
{
    T v;
    for (std::size_t i = 0; i < N; ++i)
        v.push_back(get_set<typename T::value_type>(i));
    if (some_test)
        return v;
    return T();
}

template<typename T>
float time_it()
{
    clock_t t1, t2, t3, t4;
    clock_t t0 = clock();
    {
    T v(generate<T>());
    }
    return (float)((t4-t0)/(double)CLOCKS_PER_SEC);
}

int main()
{
  try {
    std::cout << "N = " << N << "

";

    std::cout << "StaticVector Benchmark:
";
    float t = time_it<boost::StaticVector<std::set<std::size_t>,N > >();
    std::cout << "Total time = " << t << "

";

    std::cout << "Vector: Benchmark
";
    t = time_it<std::vector<std::set<std::size_t> > >();
    std::cout << "Total time = " << t <<  
 ;
  }catch(std::exception e){
    std::cout << e.what();
  }
}

bool some_test = true;

这里是StaticVector.hpp:

/**
 * @file   StaticVector.hpp
 * @date   Feb 23, 2011
 * @brief  Vector style class with fixed capacity.
 *
 * The following code declares class StaticVector,
 * an STL container (as wrapper) for a statically allocated vector with a constant size limit.
 *  StaticVector is not accepted as part of boost.
 *
 * (C) Carnegie Mellon University 2011
 * @author Andrew Hundt <ahundt@cmu.edu>
 *
 * based on boost::array
 * The original author site of boost::array is at: http://www.josuttis.com/
 * (C) Copyright Nicolai M. Josuttis 2001.
 *
 * Distributed under the Boost Software License, Version 1.0. (See
 * accompanying file LICENSE_1_0.txt or copy at
 * http://www.boost.org/LICENSE_1_0.txt)
 *
 * 09 Oct 2011 - (ath) eliminated construction of objects on initialization of StaticVector
 * 23 Feb 2011 - (ath) converted to boost::StaticVector
 * 28 Dec 2010 - (mtc) Added cbegin and cend (and crbegin and crend) for C++Ox compatibility.
 * 10 Mar 2010 - (mtc) fill method added, matching resolution of the standard library working group.
 *      See <http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#776> or Trac issue #3168
 *      Eventually, we should remove "assign" which is now a synonym for "fill" (Marshall Clow)
 * 10 Mar 2010 - added workaround for SUNCC and !STLPort [trac #3893] (Marshall Clow)
 * 29 Jan 2004 - c_array() added, BOOST_NO_PRIVATE_IN_AGGREGATE removed (Nico Josuttis)
 * 23 Aug 2002 - fix for Non-MSVC compilers combined with MSVC libraries.
 * 05 Aug 2001 - minor update (Nico Josuttis)
 * 20 Jan 2001 - STLport fix (Beman Dawes)
 * 29 Sep 2000 - Initial Revision (Nico Josuttis)
 *
 * Jan 29, 2004
 */

#ifndef BOOST_STATIC_VECTOR_HPP
#define BOOST_STATIC_VECTOR_HPP

#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>

#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)  
# pragma warning(push)  
# pragma warning(disable:4996) //  std::equal : Function call with parameters that may be unsafe
# pragma warning(disable:4510) // boost::StaticVector<T,N>  : default constructor could not be generated
# pragma warning(disable:4610) // warning C4610: class  boost::StaticVector<T,N>  can never be instantiated - user defined constructor required
#endif

#include <cstddef>
#include <stdexcept>
#include <boost/assert.hpp>
#if ((BOOST_VERSION / 100) % 1000) > 44
#include <boost/swap.hpp>
#endif
// Handles broken standard libraries better than <iterator>
#include <boost/detail/iterator.hpp>
#include <boost/throw_exception.hpp>
#include <algorithm>

// FIXES for broken compilers
#include <boost/config.hpp>

// Selection of types for internal storage
#include <boost/integer.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>


namespace boost {

    template<class T, std::size_t N>
    class StaticVector {
      public:
        // type definitions
        typedef T                                              value_type;
        typedef T*                                             pointer;
        typedef const T*                                       const_pointer;
        typedef T*                                             iterator;
        typedef const T*                                       const_iterator;
        typedef T&                                             reference;
        typedef const T&                                       const_reference;
        typedef typename boost::aligned_storage<               
                           sizeof(T),                          
                           boost::alignment_of<T>::value       
                         >::type                               aligned_storage;
        typedef typename boost::uint_value_t<N>::least         size_type;
        typedef std::size_t                                    max_size_type;
        typedef std::ptrdiff_t                                 difference_type;

      private:
        size_type m_size; // fastest type that can accomodate N
        aligned_storage elems[N];    // fixed-size array of memory aligned elements of type T

      public:

        // iterator support
        iterator        begin()       { return reinterpret_cast<iterator>(elems); }
        const_iterator  begin() const { return reinterpret_cast<const_iterator>(elems); }
        const_iterator cbegin() const { return reinterpret_cast<const_iterator>(elems); }

        iterator        end()       { return to_object(m_size); }
        const_iterator  end() const { return to_object(m_size); }
        const_iterator cend() const { return to_object(m_size); }

        // reverse iterator support
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
        typedef std::reverse_iterator<iterator> reverse_iterator;
        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
#elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
        // workaround for broken reverse_iterator in VC7
        typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
                                      reference, iterator, reference> > reverse_iterator;
        typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
                                      const_reference, iterator, reference> > const_reverse_iterator;
#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) 
        typedef std::reverse_iterator<iterator, std::random_access_iterator_tag, 
              value_type, reference, iterator, difference_type> reverse_iterator; 
        typedef std::reverse_iterator<const_iterator, std::random_access_iterator_tag,
              value_type, const_reference, const_iterator, difference_type> const_reverse_iterator;
#else
        // workaround for broken reverse_iterator implementations
        typedef std::reverse_iterator<iterator,T> reverse_iterator;
        typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
#endif

        reverse_iterator rbegin() { return reverse_iterator(end()); }
        const_reverse_iterator rbegin() const {
            return const_reverse_iterator(end());
        }
        const_reverse_iterator crbegin() const {
            return const_reverse_iterator(end());
        }

        reverse_iterator rend() { return reverse_iterator(begin()); }
        const_reverse_iterator rend() const {
            return const_reverse_iterator(begin());
        }
        const_reverse_iterator crend() const {
            return const_reverse_iterator(begin());
        }

        StaticVector():m_size(0){}

        StaticVector(size_type n, const_reference value):
          m_size(n)
        {
          insert(begin(),n,value);
        }

        template<typename InputIterator>
        StaticVector(InputIterator first, InputIterator last):
          m_size(last-first)
        {
          capacitycheck(size());
          std::copy(first,last,begin());
        }

        template<std::size_t SizeRHS>
        StaticVector(const StaticVector<T,SizeRHS>& rhs):
          m_size(rhs.size())
        {
          capacitycheck(rhs.size());
          std::copy(rhs.begin(),rhs.end(),begin());
        }

        ~StaticVector(){
          destroy_array(::boost::has_trivial_destructor<T>());
          m_size=0;
        }

        void push_back (const_reference x){
          capacitycheck(size()+1);

          new (to_object(size())) T(x);
          m_size++;
        }

        void pop_back(){
          if(!empty()){
            to_object(size()-1)->~T();
            m_size--;
          } else {
            boost::throw_exception( std::out_of_range("StaticVector<> pop called on empty container."));
          }
        }

        iterator insert(iterator pos, const_reference x){
          capacitycheck(size()+1);
          std::copy_backward(pos,end(),end()+1);
          *pos = x;
          m_size++;
          return pos;
        }

        void insert(iterator pos, max_size_type n, const_reference x){
          capacitycheck(size()+n);
          std::copy_backward(pos,end(),end()+n);
          std::fill(pos,pos+n,x);
          m_size+=n;
        }

        template <typename InputIterator>
        void insert(iterator pos, InputIterator first, InputIterator last){
          max_size_type n = last - first;
          capacitycheck(size()+n);
          std::copy_backward(pos,end(),end()+n);
          std::copy(first,last,pos);
        }

        iterator erase(iterator pos){
          rangecheck(pos-begin());
          pos->~T();
          std::copy(pos+1,end(),pos);
          m_size--;
          return pos;
        }

        iterator erase(iterator first, iterator last){
          std::ptrdiff_t n = last-first;
            if (n>0) {
            rangecheck(size()-n);
            for(iterator it = first; it!=last; it++){
              it->~T();
            }
            std::copy(last,end(),first);
            m_size -= n;
          }
          return first;
        }

        void clear(){
          erase(begin(),end());
        }

        void resize(max_size_type n, const_reference t = T() ){
          capacitycheck(n);
          if(n - m_size > 0){
            std::fill_n(end(), n-m_size, t);
          } else {
            erase(begin()+n,end());
          }
      m_size = n;
    }

        void reserve(max_size_type n){
          capacitycheck(n);
        }

        // operator[]
        reference operator[](max_size_type i) 
        { 
            BOOST_ASSERT( i < N || i < size() && "StaticVector<>: out of range" );
            return *to_object(i);
        }

        const_reference operator[](max_size_type i) const 
        {     
            BOOST_ASSERT( i < N || i < size() && "StaticVector<>: out of range" );
            return *to_object(i); 
        }

        // at() with range check
        reference at(max_size_type i) { rangecheck(i); return *to_object(i); }
        const_reference at(max_size_type i) const { rangecheck(i); return *to_object(i); }

        // front() and back()
        reference front() 
        { 
            return begin(); 
        }

        const_reference front() const 
        {
            return begin();
        }

        reference back() 
        { 
            return *to_object(size()-1);
        }

        const_reference back() const 
        { 
            return *to_object(size()-1);
        }

        // capacity is constant, size varies
        max_size_type size() const { return m_size; }
        static max_size_type capacity() { return N; }
        bool empty() { return m_size == 0; }
        static max_size_type max_size() { return N; }
        enum { static_size = N };

        // swap (note: linear complexity)
        void swap (StaticVector<T,N>& y) {
#if ((BOOST_VERSION / 100) % 1000) > 44
            for (size_type i = 0; i < N; ++i)
                boost::swap(*to_object(i),*y.to_object(i));
            boost::swap(m_size,y.m_size);
#else
            std::swap_ranges(begin(),end(),y.begin());
            std::swap(m_size,y.m_size);
#endif
        }

        // direct access to data (read-only)
        const_pointer data() const { return elems; }
        pointer data() { return elems; }

        // use array as C array (direct read/write access to data)
        pointer c_array() { return elems; }

        // assignment with type conversion
        template <typename T2>
        StaticVector<T,N>& operator= (const StaticVector<T2,N>& rhs) {
            std::copy(rhs.begin(),rhs.end(), begin());
            m_size = rhs.size();
            return *this;
        }

        // assign one value to all elements
        void assign (const T& value) { fill ( value ); }    // A synonym for fill
        void fill   (const T& value)
        {
            std::fill_n(begin(),size(),value);
        }

        // check range (may be private because it is static)
       void rangecheck (max_size_type i) const {
            if (i >= size()) {
                std::out_of_range e("StaticVector<>: index out of range");
                boost::throw_exception(e);
            }
        }

       // check range (may be private because it is static)
      void capacitycheck (max_size_type i) const {
           if (i > capacity()) {
               std::out_of_range e("StaticVector<>: index out of capacity");
               boost::throw_exception(e);
           }
       }

private:
    inline const_pointer to_object(size_type index) const {
        return reinterpret_cast<const_pointer>(elems+index);
    }

    inline pointer to_object(size_type index) {
        return reinterpret_cast<pointer>(elems+index);
    }

    // T has a trivial destructor, do nothing
    inline void destroy_array(const boost::true_type&) {}

    // T has a destructor, destroy each object 
    inline void destroy_array(const boost::false_type&) {
        for(iterator first = begin(); first != end(); ++first) {
           first->~T();
        }
    }
}; // class StaticVector

#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
    template< class T >
    class StaticVector< T, 0 > {

      public:
        // type definitions
        typedef T                                              value_type;
        typedef T*                                             iterator;
        typedef const T*                                       const_iterator;
        typedef T&                                             reference;
        typedef const T&                                       const_reference;
        typedef typename boost::aligned_storage<               
                           sizeof(T),                          
                           boost::alignment_of<T>::value       
                         >::type                               aligned_storage;
        typedef typename boost::uint_value_t<0>::least         size_type;
        typedef std::size_t                                    max_size_type;
        typedef std::ptrdiff_t                                 difference_type;

        // iterator support
        iterator        begin()       { return       iterator( reinterpret_cast<       T * >( this ) ); }
        const_iterator  begin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); }
        const_iterator cbegin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); }

        iterator        end()       { return  begin(); }
        const_iterator  end() const { return  begin(); }
        const_iterator cend() const { return cbegin(); }

        // reverse iterator support
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
        typedef std::reverse_iterator<iterator> reverse_iterator;
        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
#elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
        // workaround for broken reverse_iterator in VC7
        typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
                                      reference, iterator, reference> > reverse_iterator;
        typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
                                      const_reference, iterator, reference> > const_reverse_iterator;
#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) 
        typedef std::reverse_iterator<iterator, std::random_access_iterator_tag, 
              value_type, reference, iterator, difference_type> reverse_iterator; 
        typedef std::reverse_iterator<const_iterator, std::random_access_iterator_tag,
              value_type, const_reference, const_iterator, difference_type> const_reverse_iterator;
#else
        // workaround for broken reverse_iterator implementations
        typedef std::reverse_iterator<iterator,T> reverse_iterator;
        typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
#endif

        reverse_iterator rbegin() { return reverse_iterator(end()); }
        const_reverse_iterator rbegin() const {
            return const_reverse_iterator(end());
        }
        const_reverse_iterator crbegin() const {
            return const_reverse_iterator(end());
        }

        reverse_iterator rend() { return reverse_iterator(begin()); }
        const_reverse_iterator rend() const {
            return const_reverse_iterator(begin());
        }
        const_reverse_iterator crend() const {
            return const_reverse_iterator(begin());
        }

        void push_back (const_reference x){
          failed_rangecheck();
        }

        void pop_back(){
          failed_rangecheck();
        }

        iterator insert(iterator pos, const_reference x){
          return failed_rangecheck();
        }

        void insert(iterator pos, max_size_type n, const_reference x){
          failed_rangecheck();
        }

        template <typename InputIterator>
        void insert(iterator pos, InputIterator first, InputIterator last){
          failed_rangecheck();
        }

        iterator erase(iterator pos){
          return failed_rangecheck();
        }

        iterator erase(iterator first, iterator last){
          return failed_rangecheck();
        }

        void clear(){
        }

        void resize(max_size_type n, const_reference t = T() ){
          failed_rangecheck();
        }

        void reserve(size_type n){
          failed_rangecheck();
        }

        // operator[]
        reference operator[](max_size_type /*i*/)
        {
            return failed_rangecheck();
        }

        const_reference operator[](max_size_type /*i*/) const
        {
            return failed_rangecheck();
        }

        // at() with range check
        reference at(max_size_type /*i*/)               {   return failed_rangecheck(); }
        const_reference at(max_size_type /*i*/) const   {   return failed_rangecheck(); }

        // front() and back()
        reference front()
        {
            return failed_rangecheck();
        }

        const_reference front() const
        {
            return failed_rangecheck();
        }

        reference back()
        {
            return failed_rangecheck();
        }

        const_reference back() const
        {
            return failed_rangecheck();
        }

        // size is constant
        static max_size_type size() { return 0; }
        static bool empty() { return true; }
        static max_size_type max_size() { return 0; }
        enum { static_size = 0 };

        void swap (StaticVector<T,0>& /*y*/) {
        }

        // direct access to data (read-only)
        const T* data() const { return 0; }
        T* data() { return 0; }

        // use array as C array (direct read/write access to data)
        T* c_array() { return 0; }

        // assignment with type conversion
        template <typename T2>
        StaticVector<T,0>& operator= (const StaticVector<T2,0>& ) {
            return *this;
        }

        // assign one value to all elements
        void assign (const T& value) { fill ( value ); }
        void fill   (const T& ) {}

        // check range (may be private because it is static)
        static reference failed_rangecheck () {
                std::out_of_range e("attempt to access element of an empty StaticVector");
                boost::throw_exception(e);
#if defined(BOOST_NO_EXCEPTIONS) || !defined(BOOST_MSVC)
                //
                // We need to return something here to keep
                // some compilers happy: however we will never
                // actually get here....
                //
                static T placeholder;
                return placeholder;
#endif
            }
    };
#endif

    // comparisons
    template<class T, std::size_t N>
    bool operator== (const StaticVector<T,N>& x, const StaticVector<T,N>& y) {
        return std::equal(x.begin(), x.end(), y.begin());
    }
    template<class T, std::size_t N>
    bool operator< (const StaticVector<T,N>& x, const StaticVector<T,N>& y) {
        return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
    }
    template<class T, std::size_t N>
    bool operator!= (const StaticVector<T,N>& x, const StaticVector<T,N>& y) {
        return !(x==y);
    }
    template<class T, std::size_t N>
    bool operator> (const StaticVector<T,N>& x, const StaticVector<T,N>& y) {
        return y<x;
    }
    template<class T, std::size_t N>
    bool operator<= (const StaticVector<T,N>& x, const StaticVector<T,N>& y) {
        return !(y<x);
    }
    template<class T, std::size_t N>
    bool operator>= (const StaticVector<T,N>& x, const StaticVector<T,N>& y) {
        return !(x<y);
    }

    // global swap()
    template<class T, std::size_t N>
    inline void swap (StaticVector<T,N>& x, StaticVector<T,N>& y) {
        x.swap(y);
    }

#if defined(__SUNPRO_CC)
//  Trac ticket #4757; the Sun Solaris compiler can t handle
//  syntax like  T(&get_c_array(boost::StaticVector<T,N>& arg))[N] 
//  
//  We can t just use this for all compilers, because the 
//      borland compilers can t handle this form. 
    namespace detail {
       template <typename T, std::size_t N> struct c_array
       {
           typedef T type[N];
       };
    }

   // Specific for boost::StaticVector: simply returns its elems data member.
   template <typename T, std::size_t N>
   typename detail::c_array<T,N>::type& get_c_array(boost::StaticVector<T,N>& arg)
   {
       return arg.elems;
   }

   // Specific for boost::StaticVector: simply returns its elems data member.
   template <typename T, std::size_t N>
   typename const detail::c_array<T,N>::type& get_c_array(const boost::StaticVector<T,N>& arg)
   {
       return arg.elems;
   }
#else
// Specific for boost::StaticVector: simply returns its elems data member.
    template <typename T, std::size_t N>
    T(&get_c_array(boost::StaticVector<T,N>& arg))[N]
    {
        return arg.elems;
    }

    // Const version.
    template <typename T, std::size_t N>
    const T(&get_c_array(const boost::StaticVector<T,N>& arg))[N]
    {
        return arg.elems;
    }
#endif

#if 0
    // Overload for std::array, assuming that std::array will have
    // explicit conversion functions as discussed at the WG21 meeting
    // in Summit, March 2009.
    template <typename T, std::size_t N>
    T(&get_c_array(std::array<T,N>& arg))[N]
    {
        return static_cast<T(&)[N]>(arg);
    }

    // Const version.
    template <typename T, std::size_t N>
    const T(&get_c_array(const std::array<T,N>& arg))[N]
    {
        return static_cast<T(&)[N]>(arg);
    }
#endif


} /* namespace boost */


#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)  
# pragma warning(pop)  
#endif 

#endif /*BOOST_STATIC_VECTOR_HPP*/
最佳回答

页: 1 你们需要一台复印机。 请注意,贵方的构造人const StaticVector<T,SizeRHS>&不是复印件,因为它是一个模板。 因此,如果复制(例如,如果从一项功能中返回),则编辑制作的复印件制造器被使用,复制存储器(这张oka,是个POD)。 在销毁时,离轨器可进入储存,因为它含有活物体,而且可怕。

问题回答

<代码>boost:ed_storage实际上是个POD型(需要C++11),对储存的类型没有了解。 它只是提供储存。 如果你想要将物体从一个储存地复制到另一个储存地,你将不得不进行复印。

您是否认为是执行你自己的分配器,其基础是 st储存,再使用标准集装箱?





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签