c++ - 具有模板模板参数的类模板特化

标签 c++ c++11 templates

我正在尝试将一个类专门化为 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 一起使用时,一切都按预期工作。

有人可以解释为什么常量性在这种情况下禁止类型推导(匹配?)。

编辑(更新代码):

这是一个完全可编译的片段。我试图捕获此代码段中的最小示例。原始链接已更新以反射(reflect)此示例。

#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.
}

删除 main 的第 2 行的注释会触发静态断言。我也试过 std::decay 和 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>
{};

关于c++ - 具有模板模板参数的类模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48293482/

相关文章:

c++ - 如何 shellexecute 临时安装程序文件?

c++ - 将指向数组的指针传递给 C 和 C++ 中的函数的两个不同结果?

C++ 为什么迭代器在与 find 函数一起使用时表现不同?

c++ - 为什么 unique_ptr 有一个 nullptr_t 构造函数?

c++ - 函数对象方法对函数指针安全吗?

c++ - 尝试在 PortMidi 中打开输入

c++ - 排序可能已经排序的序列——STL::sort efficiency

C++ - 混合默认成员初始值设定项和成员初始化列表 - 坏主意?

c++ - 模板类型的 ADL 和友元函数

c++ - 如何使用具有特定方法的类实例化 C++ 模板