在部分特化模板参数中使用模板参数时,是否有办法解决标准的局限性?我想使它工作的代码是这样的:涉及模板参数的模板参数
template<typename L, size_t offset, typename enable_if< (offset<sizeof(L)), int >::type =0>
class a{};
template<typename L>
class a<L, sizeof(L)-1>{};
在部分特化模板参数中使用模板参数时,是否有办法解决标准的局限性?我想使它工作的代码是这样的:涉及模板参数的模板参数
template<typename L, size_t offset, typename enable_if< (offset<sizeof(L)), int >::type =0>
class a{};
template<typename L>
class a<L, sizeof(L)-1>{};
因为它是C++ 11,你可以简单地使用static_assert
的一般条件。对于sizeof(L)-1
的事情,你需要使用enable_if
技巧,因为它需要一些专门的东西。例如:
#include <cstdlib>
#include <type_traits>
#include <cstdio>
template <typename L, size_t offset, typename = void>
class a
{
static_assert(offset < sizeof(L), "something's wrong");
public:
void f()
{
printf("generic\n");
}
};
template <typename L, size_t offset>
class a<L, offset, typename std::enable_if<offset == sizeof(L)-1>::type>
{
// note: the static_assert is *not* inherited here.
public:
void f()
{
printf("specialized\n");
}
};
int main()
{
static_assert(sizeof(int) == 4, "oops");
a<int, 3> x;
a<int, 2> y;
x.f();
y.f();
return 0;
}
你的代码不会编译,事实上真正的问题(模板参数中的'sizeof(L)-1')仍然存在。 – 2012-01-31 13:02:05
@LorenzoPistone:检查更新。 – kennytm 2012-01-31 13:12:13
太好了。还有一个问题:在这里,我是否认为类模板与主类中的调用相匹配,但是专用版本是首选的,因为它确实是专用的? – 2012-01-31 13:46:50
我不知道这是否是你的意思。这是你可以选择不同的实现,如果第二个模板arguemnt第一个模板参数的大小相匹配 - 1.
template<typename L, size_t offset>
class aImplMatch
{ // choose this if offset == sizeof(L) - 1
L v;
};
template<typename L, size_t offset>
class aImpl
{
L v;
char off[offset];
};
template<typename L, size_t offset, size_t i>
struct SelectImpl{};
template<typename L, size_t offset>
struct SelectImpl<L, offset, 0> { typedef aImplMatch<L, offset> Result; };
template<typename L, size_t offset>
struct SelectImpl<L, offset, 1> { typedef aImpl<L, offset> Result; };
template<typename L, size_t offset>
class a
{
enum {I = offset == sizeof(offset) - 1 ? 0 : 1 };
typedef typename SelectImpl<L, offset, I>::Result Impl;
Impl impl;
};
也许它可以做的更好/更容易,这是我的第一个想法......
从代码中不清楚你的意思。假设代码可以编译,基本上(如果我理解正确的话)定义一个带有两个参数类型和偏移量的模板,如果用户没有提供,其中第二个参数默认为'sizeof(L)-1' ...很简单:'template class a {};'但我明白那不是你的意图。当问你应该说明你的意思,而不仅仅是非工作代码。当你谈论你知道不支持的代码时更是如此。 –
2012-01-31 13:17:51