【发布时间】:2014-05-05 17:50:41
【问题描述】:
(注意:我找不到合适的标题)
我正在使用 Visual Studio 2013。 我的项目中有以下代码:
template< class ConditionType >
class Not
{
ConditionType m_condition;
public:
using this_type = Not<ConditionType>;
template< class ...Args
, typename = std::enable_if<
!std::is_same< this_type, typename std::decay<Args>::type...>::value
>::type
>
Not( Args&&... args )
: m_condition( std::forward<Args>(args)... ) {}
Not( const Not& ) = default;
Not& operator=( const Not& ) = default;
template< class ...Args >
bool operator()( Args&&... args ) const
{
return ! m_condition( std::forward<Args>(args)... );
}
friend inline bool operator==( const Not& left, const Not& right )
{
return left.m_condition == right.m_condition;
}
friend inline bool operator<( const Not& left, const Not& right )
{
return left.m_condition < right.m_condition;
}
};
明显的目的是我有一个 ConditionType,它是一个可比较的函数对象,我想得到一个与之相对应的类型。 例如:
class KeyIsPressed
{
KeyId m_key;
public:
KeyIsPressed( KeyId key ) : m_key( std::move(key) ) {}
bool operator()( const InputStateBuffer& states ) const
{
return states.current().keyboard().is_key_pressed( m_key );
}
friend inline bool operator==( const KeyIsPressed& left, const KeyIsPressed& right )
{
return left.m_key == right.m_key;
}
friend inline bool operator<( const KeyIsPressed& left, const KeyIsPressed& right )
{
return left.m_key < right.m_key;
}
};
void somewhere( const InputStateBuffer& input_state_buffer )
{
Not<KeyIsPressed> condition { KEY_SHIFT };
if( condition( input_state_buffer ) )
do_something();
};
到目前为止,这一直很有效,直到我开始使用 不需要任何构造函数参数的条件类型。在这种情况下,Visual Studio 编译器会触发错误:
error C2512: 'blahblah::Not<blahblah::SomeConditionType>::Not' : no appropriate default constructor available
我尝试通过添加 Not 构造函数的一些条件或特化来解决此问题,但到目前为止没有任何效果。我没有看到简单的解决方案,但我对 enable_if 和相关构造的了解有限。
问题的根源是我确实需要在 Not 构造函数中使用可变参数模板参数来将构造函数参数传递给实际条件。但是,当没有参数并且可以默认构造条件时,我的代码似乎无法生成一个空的可变参数模板;可能是因为 enable_if 生成了最后一个类型。 我在构造函数中使用的 enable_if 是为了确保复制构造始终调用 Not 复制构造函数,而不是将 Not to copy 转发给条件构造函数。
我找不到的是在这种情况下如何在 Not 中允许默认构造。
编辑>
这是一个完整的复制案例:
#include <type_traits>
template< class ConditionType >
class Not
{
ConditionType m_condition;
public:
using this_type = Not<ConditionType>;
template< class ...Args
, typename = std::enable_if<
!std::is_same< this_type, typename std::decay<Args>::type...>::value
>::type
>
Not( Args&&... args )
: m_condition( std::forward<Args>(args)... ) {}
Not( const Not& ) = default;
Not& operator=( const Not& ) = default;
template< class ...Args >
bool operator()( Args&&... args ) const
{
return ! m_condition( std::forward<Args>(args)... );
}
friend inline bool operator==( const Not& left, const Not& right )
{
return left.m_condition == right.m_condition;
}
friend inline bool operator<( const Not& left, const Not& right )
{
return left.m_condition < right.m_condition;
}
};
class ConditionThatCompile
{
int m_key;
public:
ConditionThatCompile( int key ) : m_key( key ) {}
bool operator()( const int& value ) const
{
return m_key > value;
}
friend inline bool operator==( const ConditionThatCompile& left, const ConditionThatCompile& right )
{
return left.m_key == right.m_key;
}
friend inline bool operator<( const ConditionThatCompile& left, const ConditionThatCompile& right )
{
return left.m_key < right.m_key;
}
};
class ConditionThatDoNotCompile
{
public:
bool operator()( const int& value ) const
{
return true;
}
friend inline bool operator==( const ConditionThatDoNotCompile& left, const ConditionThatDoNotCompile& right )
{
return true;
}
friend inline bool operator<( const ConditionThatDoNotCompile& left, const ConditionThatDoNotCompile& right )
{
return false;
}
};
void do_something();
void somewhere()
{
Not<ConditionThatCompile> compiling_condition { 42 };
if( compiling_condition( 100 ) )
do_something();
Not<ConditionThatDoNotCompile> not_compiling_condition;
};
【问题讨论】:
-
嗯...如果您可以创建一个小的、可编译的示例来显示问题,它可能会有所帮助。
-
你不能实现默认构造函数
Not(void){}? -
将
Not() = default;添加到类并相应地编写另一个构造函数。 -
似乎
std::is_same< this_type, typename std::decay<Args>::type...>::value在没有参数的情况下无法匹配,因为基本上Args是“空”然后(另外:这段代码是否适用于多个参数?看起来这种情况不'也不匹配模板)。 -
@Rubens 应该是
Not(){}我不知道为什么 C++ 标准仍然支持 C 语法。更糟糕的是,VS 模板使用它...
标签: c++ c++11 visual-studio-2013