MSVC ++ 14中的C ++ 11代码不太可能 [英] Impossibly fast Delegate in C++11 on MSVC++14
问题描述
问题
这个问题涉及到这里的函数指针的几个问题(我不会列出它们),但最重要的是它涉及到代码这里。该帖子声称该代码应该是标准兼容的,它在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:
#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
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:
#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屋!