MSVC ++ 14中的C ++ 11代码不太可能 [英] Impossibly fast Delegate in C++11 on MSVC++14

查看:276
本文介绍了MSVC ++ 14中的C ++ 11代码不太可能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题



这个问题涉及到这里的函数指针的几个问题(我不会列出它们),但最重要的是它涉及到代码这里。该帖子声称该代码应该是标准兼容的,它在Apple Clang上编译很好。



我没有设法在VS2015中编译它即MSVC ++ 14。



可能是这个错误的根源,为什么不用Clang?






第一个错误



首次错误重复多次:

  ... \Delegate.hpp(329):错误C2514:'Delegate< R(A ...)> :: is_member_pair<<符号>>':
类没有构造函数

is_member_pair_const 。它涉及以下代码部分:

  template< typename T> 
static typename :: std :: enable_if<
!(is_member_pair< T> {} ||
is_const_member_pair< T> {}),
R> :: type
functor_stub(void * const object_ptr,A& ... args)
{
return(* static_cast< T *>(object_ptr))(:: std :: forward< A>(args)...);
}






第二个错误



出现多个错误,但第一个通常是最重要的:

  .. .\Delegate.hpp(340):错误C2059:语法错误:'< end Parse>'
... \Delegate.hpp(349):注意:请参阅类模板实例化引用 R(A ...)>'被编译

然后按照一些语法错误,无法识别的模板声明/定义等。有关代码:

 模板< typename T> 
static typename :: std :: enable_if<
is_member_pair< T> {} ||
is_const_member_pair< T> {},
R
> :: type
functor_stub(void * const object_ptr,A&& ... args)
{
return(static_cast< T *>(object_ptr) - > first-> *
static_cast< T *>(object_ptr) - > second)(:: std :: forward& ;(args)...);
}






为了完整性:整个Delegate.hpp:



代码来源 Base文章

  #pragma once 
#ifndef DELEGATE_HPP
#define DELEGATE_HPP

#include< cassert>

#include<内存>

#include< new>

#include< type_traits>

#include< utility>

模板< typename T>班级代表

template< class R,class ... A>
class Delegate< R(A ...)>
{
使用stub_ptr_type = R(*)(void *,A&& ...);

代理(void * const o,stub_ptr_type const m)noexcept:
object_ptr_(o),
stub_ptr_(m)
{
}

public:
Delegate()= default;

委托(代理const&)=默认;

代表(代表&&)=默认;

委托(:: std :: nullptr_t const)noexcept:Delegate(){}

模板< class C,typename =
typename :: std: :enable_if< :: std :: is_class< C> {}> :: type>
显式代理(C const * const o)noexcept:
object_ptr_(const_cast< C *>(o))
{
}

模板< class C,typename =
typename :: std :: enable_if< :: std :: is_class< C> {}> :: type>
explicit Delegate(C const& o)noexcept:
object_ptr_(const_cast< C *>(& o))
{
}

模板< class C>
代理(C * const object_ptr,R(C :: * const method_ptr)(A ...))
{
* this = from(object_ptr,method_ptr);
}

模板< class C>
代理(C * const object_ptr,R(C :: * const method_ptr)(A ...)const)
{
* this = from(object_ptr,method_ptr);
}

模板< class C>
委托(C& object,R(C :: * const method_ptr)(A ...))
{
* this = from(object,method_ptr);
}

模板< class C>
代理(C const& object,R(C :: * const method_ptr)(A ...)const)
{
* this = from(object,method_ptr);
}

模板<
typename T,
typename = typename :: std :: enable_if<
!:: std :: is_same< Delegate,typename :: std :: decay< T> :: type> {}
> :: type
>
代理(T&& f):
store_(operator new(sizeof(typename :: std :: decay< T> :: type)),
functor_deleter< typename :: std $ dec $< T> :: type>),
store_size_(sizeof(typename :: std :: decay< T> :: type))
{
使用functor_type = typename :: std :: decay< T> :: type;

new(store_.get())functor_type(:: std :: forward< T>(f));

object_ptr_ = store_.get();

stub_ptr_ = functor_stub< functor_type> ;;

deleter_ = deleter_stub< functor_type> ;;
}

委托& operator =(Delegate const&)= default;

委托& operator =(Delegate&&)= default;

template< class C>
代表& operator =(R(C :: * const rhs)(A ...))
{
return * this = from(static_cast< C *>(object_ptr_),rhs);
}

模板< class C>
代表& operator =(R(C :: * const rhs)(A ...)const)
{
return * this = from(static_cast< C const *>(object_ptr_),rhs);
}

模板<
typename T,
typename = typename :: std :: enable_if<
!:: std :: is_same< Delegate,typename :: std :: decay< T> :: type> {}
> :: type
>
代表& operator =(T&& f)
{
using functor_type = typename :: std :: decay< T> :: type;

如果((sizeof(functor_type)> store_size_)||!store_.unique())
{
store_.reset(operator new(sizeof(functor_type)
functor_deleter< functor_type>);

store_size_ = sizeof(functor_type);
}
else
{
deleter_(store_.get());
}

new(store_.get())functor_type(:: std :: forward< T>(f));

object_ptr_ = store_.get();

stub_ptr_ = functor_stub< functor_type> ;;

deleter_ = deleter_stub< functor_type> ;;

return * this;
}

模板< R(* const function_ptr)(A ...)>
static来自()的代理noexcept
{
return {nullptr,function_stub< function_ptr> };
}

模板< class C,R(C :: * const method_ptr)(A ...)>
static来自(C * const object_ptr)的代理noexcept
{
return {object_ptr,method_stub< C,method_ptr> };
}

模板< class C,R(C :: * const method_ptr)(A ...)const>
static来自(C const * const object_ptr)的代理noexcept
{
return {const_cast< C *>(object_ptr),const_method_stub< C,method_ptr> };
}

模板< class C,R(C :: * const method_ptr)(A ...)>
static来自(C& object)的代理noexcept
{
return {& object,method_stub< C,method_ptr> };
}

模板< class C,R(C :: * const method_ptr)(A ...)const>
static来自(C const& object)的代理noexcept
{
return {const_cast< C *>(& object),const_method_stub< C,method_ptr> };
}

模板< typename T>
static代理(T&& f)
{
return :: std :: forward< T>(f);
}

static代理(R(* const function_ptr)(A ...))
{
return function_ptr;
}

模板< class C>
使用member_pair =
:: std :: pair< C * const,R(C :: * const)(A ...)> ;;

template< class C>
使用const_member_pair =
:: std :: pair< C const * const,R(C :: * const)(A ...)const> ;;

template< class C>
static来自(C * const object_ptr,
R(C :: * const method_ptr)(A ...))的代理
{
return member_pair< C>(object_ptr, method_ptr);
}

模板< class C>
static代理(C const * const object_ptr,
R(C :: * const method_ptr)(A ...)const)
{
return const_member_pair< C object_ptr,method_ptr);
}

模板< class C>
static来自(C& object,R(C :: * const method_ptr)(A ...))的代理
{
return member_pair< C>(& object,method_ptr);
}

模板< class C>
static来自(C const& object,
R(C :: * const method_ptr)(A ...)const的代理)
{
返回const_member_pair< C& ; object,method_ptr);
}

void reset(){stub_ptr_ = nullptr; store_.reset(); }

void reset_stub()noexcept {stub_ptr_ = nullptr; }

void swap(Delegate& other)noexcept {:: std :: swap(* this,other); }

bool operator ==(Delegate const& rhs)const noexcept
{
return(object_ptr_ == rhs.object_ptr_)&& (stub_ptr_ == rhs.stub_ptr_);
}

bool operator!=(Delegate const& rhs)const noexcept
{
return!operator ==(rhs);
}

bool operator<(Delegate const& rhs)const noexcept
{
return(object_ptr_< rhs.object_ptr_)||
((object_ptr_ == rhs.object_ptr_)&(stub_ptr_< rhs.stub_ptr_));
}

bool operator ==(:: std :: nullptr_t const)const noexcept
{
return!stub_ptr_;
}

bool operator!=(:: std :: nullptr_t const)const noexcept
{
return stub_ptr_;
}

显式运算符bool()const noexcept {return stub_ptr_; }

R运算符()(A ... args)const
{
// assert(stub_ptr);
return stub_ptr_(object_ptr_,:: std :: forward< A>(args)...);
}

private:
friend struct :: std :: hash< Delegate> ;;

使用deleter_type = void(*)(void *);

void * object_ptr_;
stub_ptr_type stub_ptr_ {};

deleter_type deleter_;

:: std :: shared_ptr< void>商店_;
:: std :: size_t store_size_;

模板< class T>
static void functor_deleter(void * const p)
{
static_cast< T *>(p) - >〜T();

操作符delete(p);
}

模板< class T>
static void deleter_stub(void * const p)
{
static_cast< T *>(p) - >〜T();
}

template< R(* function_ptr)(A ...)>
static R function_stub(void * const,A&& ... args)
{
return function_ptr(:: std :: forward< A>(args)...);
}

template< class C,R(C :: * method_ptr)(A ...)>
static R method_stub(void * const object_ptr,A&&args)
{
return(static_cast< C *>(object_ptr) - > * method_ptr) b $ b :: std :: forward< A>(args)...);
}

模板< class C,R(C :: * method_ptr)(A ...)const>
static R const_method_stub(void * const object_ptr,A&&args)
{
return(static_cast< C const *>(object_ptr) - > * method_ptr)
:: std :: forward< A>(args)...);
}

模板< typename>
struct is_member_pair:std :: false_type {};

template< class C>
struct is_member_pair< :: std :: pair< C * const,
R(C :: * const)(A ...)> > :std :: true_type
{
};

模板< typename>
struct is_const_member_pair:std :: false_type {};

template< class C>
struct is_const_member_pair< :: std :: pair< C const * const,
R(C :: * const)(A ...)const> > :std :: true_type
{
};

模板< typename T>
static typename :: std :: enable_if<
!(is_member_pair< T> {} ||
is_const_member_pair< T> {}),
R
> :: type
functor_stub(void * const object_ptr ,A&& ... args)
{
return(* static_cast< T *>(object_ptr))(:: std :: forward< A>(args)...);
}

模板< typename T>
static typename :: std :: enable_if<
is_member_pair< T> {} ||
is_const_member_pair< T> {},
R
> :: type
functor_stub(void * const object_ptr,A&& ... args)
{
return(static_cast< T *>(object_ptr) - > first-> *
static_cast< T *>(object_ptr) - > second)(:: std :: forward& ;(args)...);
}
};

命名空间std
{
模板< typename R,typename ... A>
struct hash< :: Delegate< R(A ...)> >
{
size_t operator()(:: Delegate< R(A ...)> const& d)const noexcept
{
auto const seed(hash< void * >()(d.object_ptr_));

return hash< typename :: Delegate< R(A ...)> :: stub_ptr_type>()(
d.stub_ptr_)+ 0x9e3779b9 +(seed<< )+(种子>> 2);
}
};
}

#endif // DELEGATE_HPP


解决方案按照Igor的评论,以下解决了这个问题:将 is_member_pair< T> {} 替换为 is_member_pair< T> ::价值到处,并为 is_const_member_pair 执行相同操作。


The Problem

This question relates to several questions about function pointers here (I will not list them), but most importantly it concerns the code posted here. The post claims the code should be standard compliant and it compiles on Apple Clang just fine.

I have not managed to compile it in VS2015, i.e. MSVC++14.

What could be the source of this error and why not with Clang?


First Error

First error repeats multiple times:

...\Delegate.hpp(329): error C2514: 'Delegate<R(A...)>::is_member_pair<<unnamed-symbol>>':
class has no constructors

And the same for is_member_pair_const. It relates to the following part of the code:

  template <typename T>
  static typename ::std::enable_if<
    !(is_member_pair<T>{} ||
    is_const_member_pair<T>{}),
    R>::type
  functor_stub(void* const object_ptr, A&&... args)
  {
    return (*static_cast<T*>(object_ptr))(::std::forward<A>(args)...);
  }


Second Error

Multiple errors appear, but the first is usually most important:

...\Delegate.hpp(340): error C2059: syntax error: '<end Parse>'
...\Delegate.hpp(349): note: see reference to class template instantiation 'Delegate<R(A...)>' being compiled

Then follow a few syntax errors, unrecognizable template declaration/definition etc. The code in question:

  template <typename T>
  static typename ::std::enable_if<
    is_member_pair<T>{} ||
    is_const_member_pair<T>{},
    R
  >::type
  functor_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<T*>(object_ptr)->first->*
      static_cast<T*>(object_ptr)->second)(::std::forward<A>(args)...);
  }


For Completeness: The entire Delegate.hpp:

Code Source and Base Article

#pragma once
#ifndef DELEGATE_HPP
#define DELEGATE_HPP

#include <cassert>

#include <memory>

#include <new>

#include <type_traits>

#include <utility>

template <typename T> class Delegate;

template<class R, class ...A>
class Delegate<R (A...)>
{
  using stub_ptr_type = R (*)(void*, A&&...);

  Delegate(void* const o, stub_ptr_type const m) noexcept :
    object_ptr_(o),
    stub_ptr_(m)
  {
  }

public:
  Delegate() = default;

  Delegate(Delegate const&) = default;

  Delegate(Delegate&&) = default;

  Delegate(::std::nullptr_t const) noexcept : Delegate() { }

  template <class C, typename =
    typename ::std::enable_if< ::std::is_class<C>{}>::type>
  explicit Delegate(C const* const o) noexcept :
    object_ptr_(const_cast<C*>(o))
  {
  }

  template <class C, typename =
    typename ::std::enable_if< ::std::is_class<C>{}>::type>
  explicit Delegate(C const& o) noexcept :
    object_ptr_(const_cast<C*>(&o))
  {
  }

  template <class C>
  Delegate(C* const object_ptr, R (C::* const method_ptr)(A...))
  {
    *this = from(object_ptr, method_ptr);
  }

  template <class C>
  Delegate(C* const object_ptr, R (C::* const method_ptr)(A...) const)
  {
    *this = from(object_ptr, method_ptr);
  }

  template <class C>
  Delegate(C& object, R (C::* const method_ptr)(A...))
  {
    *this = from(object, method_ptr);
  }

  template <class C>
  Delegate(C const& object, R (C::* const method_ptr)(A...) const)
  {
    *this = from(object, method_ptr);
  }

  template <
    typename T,
    typename = typename ::std::enable_if<
      !::std::is_same<Delegate, typename ::std::decay<T>::type>{}
    >::type
  >
  Delegate(T&& f) :
    store_(operator new(sizeof(typename ::std::decay<T>::type)),
      functor_deleter<typename ::std::decay<T>::type>),
    store_size_(sizeof(typename ::std::decay<T>::type))
  {
    using functor_type = typename ::std::decay<T>::type;

    new (store_.get()) functor_type(::std::forward<T>(f));

    object_ptr_ = store_.get();

    stub_ptr_ = functor_stub<functor_type>;

    deleter_ = deleter_stub<functor_type>;
  }

  Delegate& operator=(Delegate const&) = default;

  Delegate& operator=(Delegate&&) = default;

  template <class C>
  Delegate& operator=(R (C::* const rhs)(A...))
  {
    return *this = from(static_cast<C*>(object_ptr_), rhs);
  }

  template <class C>
  Delegate& operator=(R (C::* const rhs)(A...) const)
  {
    return *this = from(static_cast<C const*>(object_ptr_), rhs);
  }

  template <
    typename T,
    typename = typename ::std::enable_if<
      !::std::is_same<Delegate, typename ::std::decay<T>::type>{}
    >::type
  >
  Delegate& operator=(T&& f)
  {
    using functor_type = typename ::std::decay<T>::type;

    if ((sizeof(functor_type) > store_size_) || !store_.unique())
    {
      store_.reset(operator new(sizeof(functor_type)),
        functor_deleter<functor_type>);

      store_size_ = sizeof(functor_type);
    }
    else
    {
      deleter_(store_.get());
    }

    new (store_.get()) functor_type(::std::forward<T>(f));

    object_ptr_ = store_.get();

    stub_ptr_ = functor_stub<functor_type>;

    deleter_ = deleter_stub<functor_type>;

    return *this;
  }

  template <R (* const function_ptr)(A...)>
  static Delegate from() noexcept
  {
    return { nullptr, function_stub<function_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...)>
  static Delegate from(C* const object_ptr) noexcept
  {
    return { object_ptr, method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...) const>
  static Delegate from(C const* const object_ptr) noexcept
  {
    return { const_cast<C*>(object_ptr), const_method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...)>
  static Delegate from(C& object) noexcept
  {
    return { &object, method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...) const>
  static Delegate from(C const& object) noexcept
  {
    return { const_cast<C*>(&object), const_method_stub<C, method_ptr> };
  }

  template <typename T>
  static Delegate from(T&& f)
  {
    return ::std::forward<T>(f);
  }

  static Delegate from(R (* const function_ptr)(A...))
  {
    return function_ptr;
  }

  template <class C>
  using member_pair =
    ::std::pair<C* const, R (C::* const)(A...)>;

  template <class C>
  using const_member_pair =
    ::std::pair<C const* const, R (C::* const)(A...) const>;

  template <class C>
  static Delegate from(C* const object_ptr,
    R (C::* const method_ptr)(A...))
  {
    return member_pair<C>(object_ptr, method_ptr);
  }

  template <class C>
  static Delegate from(C const* const object_ptr,
    R (C::* const method_ptr)(A...) const)
  {
    return const_member_pair<C>(object_ptr, method_ptr);
  }

  template <class C>
  static Delegate from(C& object, R (C::* const method_ptr)(A...))
  {
    return member_pair<C>(&object, method_ptr);
  }

  template <class C>
  static Delegate from(C const& object,
    R (C::* const method_ptr)(A...) const)
  {
    return const_member_pair<C>(&object, method_ptr);
  }

  void reset() { stub_ptr_ = nullptr; store_.reset(); }

  void reset_stub() noexcept { stub_ptr_ = nullptr; }

  void swap(Delegate& other) noexcept { ::std::swap(*this, other); }

  bool operator==(Delegate const& rhs) const noexcept
  {
    return (object_ptr_ == rhs.object_ptr_) && (stub_ptr_ == rhs.stub_ptr_);
  }

  bool operator!=(Delegate const& rhs) const noexcept
  {
    return !operator==(rhs);
  }

  bool operator<(Delegate const& rhs) const noexcept
  {
    return (object_ptr_ < rhs.object_ptr_) ||
      ((object_ptr_ == rhs.object_ptr_) && (stub_ptr_ < rhs.stub_ptr_));
  }

  bool operator==(::std::nullptr_t const) const noexcept
  {
    return !stub_ptr_;
  }

  bool operator!=(::std::nullptr_t const) const noexcept
  {
    return stub_ptr_;
  }

  explicit operator bool() const noexcept { return stub_ptr_; }

  R operator()(A... args) const
  {
//  assert(stub_ptr);
    return stub_ptr_(object_ptr_, ::std::forward<A>(args)...);
  }

private:
  friend struct ::std::hash<Delegate>;

  using deleter_type = void (*)(void*);

  void* object_ptr_;
  stub_ptr_type stub_ptr_{};

  deleter_type deleter_;

  ::std::shared_ptr<void> store_;
  ::std::size_t store_size_;

  template <class T>
  static void functor_deleter(void* const p)
  {
    static_cast<T*>(p)->~T();

    operator delete(p);
  }

  template <class T>
  static void deleter_stub(void* const p)
  {
    static_cast<T*>(p)->~T();
  }

  template <R (*function_ptr)(A...)>
  static R function_stub(void* const, A&&... args)
  {
    return function_ptr(::std::forward<A>(args)...);
  }

  template <class C, R (C::*method_ptr)(A...)>
  static R method_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<C*>(object_ptr)->*method_ptr)(
      ::std::forward<A>(args)...);
  }

  template <class C, R (C::*method_ptr)(A...) const>
  static R const_method_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<C const*>(object_ptr)->*method_ptr)(
      ::std::forward<A>(args)...);
  }

  template <typename>
  struct is_member_pair : std::false_type { };

  template <class C>
  struct is_member_pair< ::std::pair<C* const,
    R (C::* const)(A...)> > : std::true_type
  {
  };

  template <typename>
  struct is_const_member_pair : std::false_type { };

  template <class C>
  struct is_const_member_pair< ::std::pair<C const* const,
    R (C::* const)(A...) const> > : std::true_type
  {
  };

  template <typename T>
  static typename ::std::enable_if<
    !(is_member_pair<T>{} ||
    is_const_member_pair<T>{}),
    R
  >::type
  functor_stub(void* const object_ptr, A&&... args)
  {
    return (*static_cast<T*>(object_ptr))(::std::forward<A>(args)...);
  }

  template <typename T>
  static typename ::std::enable_if<
    is_member_pair<T>{} ||
    is_const_member_pair<T>{},
    R
  >::type
  functor_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<T*>(object_ptr)->first->*
      static_cast<T*>(object_ptr)->second)(::std::forward<A>(args)...);
  }
};

namespace std
{
  template <typename R, typename ...A>
  struct hash<::Delegate<R (A...)> >
  {
    size_t operator()(::Delegate<R (A...)> const& d) const noexcept
    {
      auto const seed(hash<void*>()(d.object_ptr_));

      return hash<typename ::Delegate<R (A...)>::stub_ptr_type>()(
        d.stub_ptr_) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
    }
  };
}

#endif // DELEGATE_HPP

解决方案

As Igor commented, the following solves the problem: replace is_member_pair<T>{} with is_member_pair<T>::value everywhere and do the same for is_const_member_pair.

这篇关于MSVC ++ 14中的C ++ 11代码不太可能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆