Kir*_*sky 21 c++ templates type-traits
回答完这个问题后,我试图is_complete在Boost库中找到模板,我意识到Boost.TypeTraits中没有这样的模板.为什么Boost库中没有这样的模板?应该怎么样?
//! Check whether type complete
template<typename T>
struct is_complete
{
static const bool value = ( sizeof(T) > 0 );
};
...
// so I could use it in such a way
BOOST_STATIC_ASSERT( boost::is_complete<T>::value );
Run Code Online (Sandbox Code Playgroud)
上面的代码不正确,因为应用于sizeof不完整类型是非法的.什么是好的解决方案?在某种程度上可以在这种情况下应用SFINAE吗?
J. *_*eja 14
Alexey Malistov给出的答案可以在MSVC上使用,只需稍加修改:
namespace
{
template<class T, int discriminator>
struct is_complete {
static T & getT();
static char (& pass(T))[2];
static char pass(...);
static const bool value = sizeof(pass(getT()))==2;
};
}
#define IS_COMPLETE(X) is_complete<X,__COUNTER__>::value
Run Code Online (Sandbox Code Playgroud)
不幸的是,COUNTER预定义的宏不是标准的一部分,所以它不适用于每个编译器.
mis*_*why 11
可能有点晚了,但到目前为止,没有C++ 11解决方案适用于完整和抽象类型.
所以,你在这里.
使用VS2015(v140),g ++> = 4.8.1,clang> = 3.4,这是有效的:
template <class T, class = void>
struct IsComplete : std::false_type
{};
template <class T>
struct IsComplete< T, decltype(void(sizeof(T))) > : std::true_type
{};
Run Code Online (Sandbox Code Playgroud)
感谢Bat-Ulzii Luvsanbat:https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
使用VS2013(V120):
namespace Details
{
template <class T>
struct IsComplete
{
typedef char no;
struct yes { char dummy[2]; };
template <class U, class = decltype(sizeof(std::declval< U >())) >
static yes check(U*);
template <class U>
static no check(...);
static const bool value = sizeof(check< T >(nullptr)) == sizeof(yes);
};
} // namespace Details
template <class T>
struct IsComplete : std::integral_constant< bool, Details::IsComplete< T >::value >
{};
Run Code Online (Sandbox Code Playgroud)
这个灵感来自于互联网和静态断言模板类型名称T不完整?
template<class T>
struct is_complete {
static T & getT();
static char (& pass(T))[2];
static char pass(...);
static const bool value = sizeof(pass(getT()))==2;
};
Run Code Online (Sandbox Code Playgroud)
恐怕你无法实现这样的is_complete类型特征。@Alexey 给出的实现无法在 G++ 4.4.2 和 G++ 4.5.0 上编译:
\n\n\n错误:初始化 \xe2\x80\x98static char 的参数 1 (& is_complete::pass(T))[2] [with T = Foo]\xe2\x80\x99
\n
在我的 Mac 上,使用 G++ 4.0.1 评估不完整的is_complete<Foo>::value地方会产生比编译器错误更糟糕的结果。struct Foo;true
T在同一个程序中可以是完整的也可以是不完整的,具体取决于翻译单元,但它始终是相同的类型。因此,如上所述,is_complete<T>也始终是相同的类型。
因此,如果您尊重ODR,则不可能is_complete<T>根据其使用位置评估不同的值;is_complete<T>否则,这将意味着您有ODR 禁止的不同定义。
编辑:作为公认的答案,我自己破解了一个解决方案,该解决方案使用宏在每次使用宏时__COUNTER__实例化不同的is_complete<T, int>类型。IS_COMPLETE然而,对于 gcc,我一开始就无法让 SFINAE 工作。
| 归档时间: |
|
| 查看次数: |
3303 次 |
| 最近记录: |