通过static_assert强制执行模板类型
Enforce template type through static_assert
我正在努力理解static_assert
的有用性,我想知道它是否能帮助我执行设计,如果可以,如何执行。
我有一个通用模板类,它将自己的实现隐藏在另一个模板类中,该模板类根据模板类型的大小进行了部分专门化。以下是此设计的简要概述:
template <class T, size_t S = sizeof(T)>
struct Helper;
template <class T>
struct Helper<T, sizeof(long)>
{
static T bar();
};
// ... other specializations ...
template <class T>
class Foo
{
public:
T bar()
{
return Helper<T>::bar();
}
};
Foo仅当T
的大小由Helper的专用化支持时才受支持。例如,同时支持Foo<long>
和Foo<unsigned long>
。但是,假设用户试图构建一个Foo<bool>
。通常,这会产生错误,因为bool
的Helper的专门化没有定义,这是预期行为。
有没有办法在这个设计中使用static_assert
来为这个界面的用户提供更多有用的错误?
此外,我还想限制用户使用特定类型,即使大小可能是正确的。例如,不应允许使用Foo<float>
。目前,我所知道的执行这一点的唯一方法是在文档中进行大胆的注释。:)
如果它只能用于模板类的特殊化,那么让默认模板类引发一个静态断言:
template <class T, size_t S = sizeof(T)>
struct Helper
{
static_assert(sizeof(T) == -1, "You have to have a specialization for Helper!" );
}
只有在没有更好的专业化时才会选择默认的模板类,因此断言会上升。
您可以使用相同的技术来禁止类型,但您需要另一个用于静态断言检查的模板参数。
template <class T, class G = T, size_t S = sizeof(T)>
struct Helper
{
static_assert(sizeof(G) == -1, "You have to have a specialization for Helper!" );
}
template <class G>
struct Helper<float,G>
{
static_assert(sizeof(G) == -1, "You can't use float !" );
}
template <>
struct Helper<int>
{
//This is a good specialization
};
然后你可以用这些变量来尝试:
Helper<bool> a; //"You have to have a specialization for Helper!"
Helper<float> b; //"You can't use float !"
Helper<int> c; //compiles OK
http://en.cppreference.com/w/cpp/header/type_traits
std::is_base_of
和std::is_convertible
可以帮助您解决第一个问题,至于第二个问题,
static_assert(!std::is_same<float,T>(),"type can't be float");
希望这能帮助其他偶然发现这个问题的人,假设OP可能在被问到这个问题后的4年内找到了答案:)
我把这里的答案和注释结合起来,为这个问题找到了更好的解决方案。
我可以定义一个静态类型检查器,如下所示:
template <class A, class B>
struct CheckTypes
{
static const bool value = false;
};
template <class A>
struct CheckTypes<A, A>
{
static const bool value = true;
};
不确定标准库中是否已经存在这样的结构。无论如何,在Foo中,我可以使用检查类型和大小
static_assert((sizeof(T) == sizeof(long) || sizeof(T) == sizeof(int)) && !CheckTypes<T, float>::value, "Error!");
- 函数作为模板参数,是否对返回类型强制约束
- 如何对模板类型强制执行常量
- C++:我可以在模板参数包中强制执行至少1个agment吗
- LLVM 无法将数组类型强制转换为常量数组
- 编译器未强制执行返回协定
- 如何在 Linux 上强制执行矢量下标超出范围的调试断言
- 如何使用C++模板强制执行正式协议?
- C++类型强制转换指向常量变量的指针
- 编译错误 QT - 无法从类型强制转换
- 为什么在与静态库链接时强制执行 order(例如 source.cxx -lstatic)
- C++ 仅当模板为字符串类型时执行小写转换
- 当函数在 GCC 中没有任何返回时,如何强制执行错误?
- 强制执行执行顺序
- 在转换为较小的数值类型之前执行范围检查的安全、跨平台方法是什么
- 替换decorator模式以强制执行创建顺序
- 我可以强制执行标量类型通过 int{} 初始化为零吗?
- 如何在C++17中强制执行模板和模板模板参数之间的约束
- 使用无符号数据类型强制执行非负值和/或有效值是否是一种最佳做法
- 通过static_assert强制执行模板类型
- 有没有一种好的方法可以在C++中的可变模板中对函数参数强制执行类型限制