vda*_*vid 6 c++ templates overriding partial-specialization
我有一个模板类/结构,如下所示:
template <typename T, typename U>
struct S
{
unsigned int operator()(T t, U u) const;
};
Run Code Online (Sandbox Code Playgroud)
我想确保专业化尊重这个界面.
不幸的是,我可以使用不同的返回类型来专门化这个结构.例如,如果我部分专门返回bool而不是unsigned int,我希望得到编译器错误,但编译器似乎并不关心:
template <typename T>
struct S<T,nullptr_t>
{
bool operator()(T t, nullptr_t u) const { return 2; }
};
Run Code Online (Sandbox Code Playgroud)
示例 @ Ideone.com
在上面的示例中,应该返回专用版本,2但是由于返回类型是bool,返回值将被转换true为然后显示为1.
为什么编译器会接受这个?
如何防止程序员使用错误的返回类型(甚至错误的参数)专门化模板?
我知道我可以在基本模板类/结构中使用虚方法实现我想要的,并override在子代中使用关键字:
使用覆盖的解决方案(不编译,这很好)
但是拥有一个虚拟方法肯定会创建一个虚拟表,我想尽可能地避免这种情况,特别是因为我在运行时不需要虚拟表.除非有一个技巧可以在不构建虚拟表的情况下做同样的事情?
另外,我知道问题会更简单,如果我可以部分专门化方法或者我可以依赖非部分专业化,但前者在C++ AFAIK中是不可能的,后者不包括我在程序中需要的情况.
创建静态界面的一个好方法是使用奇怪的重复模板模式。在你的情况下,它看起来像这样:
template<class Derived, class T, class U>
constexpr bool MyTrait = std::is_same<unsigned int, decltype(std::declval<Derived>()(std::declval<T>(), std::declval<U>()))>::value;
template <typename Derived, class T, class U>
struct StaticInterface
{
unsigned int operator()(T t, U u) const{
static_assert( MyTrait<Derived, T, U>, "errr" );
return (*static_cast<const Derived *>(this))(std::forward<T>(t), std::forward<U>(u));
}
};
template <typename T, typename U>
struct S : StaticInterface<S<T, U>, T, U>
{
unsigned int operator()(T t, U u) const{ /* some implementation */}
};
template <typename T>
struct S<T, std::nullptr_t> : StaticInterface<S<T, std::nullptr_t>, T, std::nullptr_t>
{
bool operator()(T t, std::nullptr_t u) const { return 2; }
};
Run Code Online (Sandbox Code Playgroud)
要使其正常工作,函数调用必须通过如下接口完成:
template<class Derived, class T, class U>
void test(const StaticInterface<Derived, T, U> &inter){
inter(T(), U());
}
Run Code Online (Sandbox Code Playgroud)
否则,衍生的运算符将被选为首选运算符。
| 归档时间: |
|
| 查看次数: |
275 次 |
| 最近记录: |