具有模板模板参数的类模板专用化
Class template specialization with template template parameters
我试图在类型s.t.上专门化一个类,它忽略了给定类型的恒定性。在本例中,类型为模板模板参数:
template <class T, typename Enable = void>
struct bar
{
bar()
{
static_assert(!std::is_same<T,T>::value, "no implementation of bar for type T");
}
};
template <template <typename> class FooType, class T>
struct bar<FooType<T>, typename std::enable_if<std::is_same<typename std::remove_cv<FooType<T>>::type, foo<T>>::value>::type>
{};
上面的代码在GCC 4.8.4和clang 5.0(带有-std=c++11)中都抱怨,当与FooType的模板参数化匹配的类一起使用时,bar是未定义的。即使我删除了 sfinae 参数,仍然无法找到专用化。
可以在此处找到此问题的示例:https://godbolt.org/g/Cjci9C。 在上面的示例中,专用化的构造函数有一个静态断言,当与 const FooType 一起使用时,即使 sfinae 参数被硬编码为 void,也不会找到该断言。当与非常量FooType一起使用时,所有工作都按预期工作。
有人可以解释一下为什么在这种情况下恒常性禁止类型演绎(匹配?
编辑(更新的代码):
这是一个完全可编译的代码片段。我试图捕获此代码片段中的最小示例。原始链接已更新以反映此示例。
#include <assert.h>
#include <type_traits>
template <class T>
struct foo {};
template <class T, typename Enable = void>
struct bar
{
bar()
{
static_assert(!std::is_same<T,T>::value, "no implementation of bar for type T");
}
};
template <template <typename> class FooType, class T>
struct bar<FooType<T>, typename std::enable_if<std::is_same<typename std::remove_cv<FooType<T>>::type, foo<T>>::value>::type>
{};
int main()
{
bar<foo<int>> mut_foo; // This is fine.
// bar<const foo<int>> const_foo; // Error. No implementation found.
}
删除主 2 行上的注释会触发静态断言。我也尝试过std::d ecay和std::remove_const但没有成功。
编辑(非重复理由):
虽然链接的问题确实会引发类似的问题,但它不需要使用模板模板参数。它也只提供了一种解决问题的技术,并没有证明为什么给定的代码片段不起作用。有趣的是,该技术似乎不适用于模板模板参数,因为将以下代码片段替换为上面的示例会导致相同的错误:
template <template <typename> class FooType, class T>
struct bar<FooType<T>,
typename std::enable_if<std::is_same<FooType<T>, foo<T>>::value || std::is_same<FooType<T>, const foo<T>>::value>::type>
{};
const foo<int>
不匹配FooType<T>
,
它将匹配const FooType<T>
或T
(或const T
)。
在专业化匹配之后,您可以添加 SFINAE:
所以,在你的情况下,你可以这样做
template <typename T> struct is_foo : std::false_type {};
template <typename T> struct is_foo<foo<T>> : std::true_type {};
template <class T>
struct bar<T,
typename std::enable_if<is_foo<typename std::remove_cv<T>::type>::value>::type>
{};
相关文章:
- 具有常量引用参数的函数模板专用化
- 通过依赖类型使用非类型模板参数的单类型模板参数类模板的部分专用化
- 具有多个参数的模板化类专用化,其中一个模板参数是模板本身
- 具有可变参数非类型参数的模板专用化
- 类专用化,没有用作专用化模板参数的类的模板参数
- 基于枚举参数调用专用模板方法
- 检查类是否具有模板专用化(使用布尔值或 int 等模板参数)
- 专用于可变参数模板成员函数
- 如何将模板类专用化为也接受模板模板参数
- 调用模板专用化,具有更多参数的单参数模板调用的特定值
- 有没有办法根据 lambda 参数返回类型部分专用化我的模板化函数?
- C++ 将派生类的成员函数指针作为参数传递时选择了错误的模板专用化
- cpp 模板专用化,错误说参数 1 的类型为 T,这取决于参数 T
- 具有不同非类型模板参数的模板类部分专用化
- 带有void类型和参数的C++11模板专用化
- 类模板专用化演绎是否应该考虑演绎指南参数初始化?
- 使用模板模板参数进行模板定义的函数专用化
- 在模板专用化中使用非类型模板模板参数
- C++具有可变参数专用参数的模板,用于参数数量
- 具有专用参数的类方法