Sam*_*rsa 5 c++ templates static-assert
我们有复杂的模板类,其中有一些方法不适用于某些策略或类型.因此,当我们检测到这些类型时(在编译时,使用类型特征),我们使用一条好消息来激活一个静态断言.
现在我们也进行了大量的手动模板实例化.部分原因是这些方法被迫编译器对语法进行语法检查.它还减少了库用户的编译时间.问题是静态断言总是被触发,因此我们无法手动实例化有问题的模板类.
这有解决方法吗?
编辑:为了使它更清楚,这是一个例子(在这种情况下显式实例化将在someFunc1()上失败:
// header
template <typename T>
class someClass
{
void someFunc() {}
void someFunc1() { static_assert(false, assertion_failed); }
};
// source
template someClass<int>; // Explicit instantiation
Run Code Online (Sandbox Code Playgroud)
EDIT2:这是另一个例子.这次你可以编译它看看我的意思.首先立即编译.代码应该编译.然后取消注释[2]并且静态断言应该触发.现在注释掉[2]和取消注释[1].静态断言将触发,因为您明确地实例化模板.我想避免删除显式实例化,因为它带来的好处(参见上面的好处).
namespace Loki
{
template<int> struct CompileTimeError;
template<> struct CompileTimeError<true> {};
}
#define LOKI_STATIC_CHECK(expr, msg) \
{ Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; }
template <typename T>
class foo
{
public:
void func() {}
void func1() { LOKI_STATIC_CHECK(sizeof(T) == 4, Assertion_error); }
};
template foo<int>;
//template foo<double>; // [1]
int main()
{
foo<int> a;
a.func1();
foo<double> b;
//b.func1(); //[2]
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我没有机会enable_if按照 bobah 的建议进行测试,但我确实想出了一个不需要 boost 的解决方案,并且在很大程度上满足了我最初的要求(我说好但不完整,最后会解释)
解决方案是在代码上放置一个虚拟模板,如果在某些选定类型下编译,该模板将失败,但在其他类型下编译则正常。所以:
struct dummyStruct {};
#define DUMMY_TEMP typename dummy
#define DUMMY_PARAM dummyStruct
namespace Loki
{
template<int> struct CompileTimeError;
template<> struct CompileTimeError<true> {};
}
#define LOKI_STATIC_CHECK(expr, msg) \
{ Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; }
template <typename T>
class foo
{
public:
void func() {}
template <typename T_Dummy>
void func1() { LOKI_STATIC_CHECK(sizeof(T) == 4, Assertion_error); }
};
template foo<int>;
template foo<double>; // [1]
int main()
{
foo<int> a;
a.func1<DUMMY_PARAM>();
foo<double> b;
//b.func1<DUMMY_PARAM>(); //[2] - this is a static error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在我的所有模板代码中,这些类型的函数(即具有静态断言或在某些类型上工作的函数,并且可能通过使用类型特征在其他类型上失败[在这种情况下,可以为不同类型选择几个不同的函数])对客户端隐藏。因此,在我的实现中,添加额外的内容dummy parameter是一个不错的妥协。
作为奖励,它让我知道这个函数被设计为仅由某些类型使用。此外,我最初的显式实例化问题通过这种简单的技术得到了解决。
| 归档时间: |
|
| 查看次数: |
933 次 |
| 最近记录: |