【问题标题】:Has template member - template template deduction有模板成员 - 模板模板扣除
【发布时间】:2015-05-04 03:46:29
【问题描述】:

假设我有以下两个测试类:

struct TestYes {
    using type = void;
    template <typename... T>
    using test = void;
};

struct TestNo { };

我想确定他们是否有这个模板成员test

对于会员type

template <typename, typename = void>
struct has_type_impl {
    using type = std::false_type;
};
template <typename T>
struct has_type_impl<T, typename T::type> {
    using type = std::true_type;
};
template <typename T>
using has_type = typename has_type_impl<T>::type;

完美运行:

static_assert( has_type<TestYes>::value, ""); // OK
static_assert(!has_type<TestNo>::value, "");  // OK

但模板成员 test 的等效项:

template <typename, template <typename...> class = std::tuple>
struct has_test_impl {
    using type = std::false_type;
};
template <typename T>
struct has_test_impl<T, T::template test> {
    using type = std::true_type;
};
template <typename T>
using has_test = typename has_test_impl<T>::type;

失败

static_assert( has_test<TestYes>::value, "");

我知道我可以像这样使用 SFINAE:

template <typename T>
struct has_test_impl {
private:
    using yes = std::true_type;
    using no = std::false_type;

    template <typename U, typename... Args>
    static auto foo(int) -> decltype(std::declval<typename U::template test<Args...>>(), yes());

    template <typename> static no foo(...);

public:
    using type = decltype(foo<T>(0));
};

template <typename T>
using has_test = typename has_test_impl<T>::type;

但我想知道为什么编译器正确地扣除了 has_type_impl 的部分特化,而它仍然保留在 has_test_impl 的第一个定义上。

提前感谢您的启发!

【问题讨论】:

标签: c++ substitution template-templates


【解决方案1】:
template<template<class...> class...>
using void_templ = void;

template <typename, typename = void>
struct has_test_impl {
    using type = std::false_type;
};
template <typename T>
struct has_test_impl<T, void_templ<T::template test>> {
    using type = std::true_type;
};

【讨论】:

  • 感谢您的回答。使用gcc 4.9.2版本,遇到this issue你应该很熟悉^^。适应模板模板,它就像一个魅力。双重感谢! :D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多