【问题标题】:Using decltype in partial template specialization在部分模板特化中使用 decltype
【发布时间】:2018-09-27 20:39:59
【问题描述】:

使用以下模板和专业化:

template<typename T, typename = void>
struct A {
    void operator()() {
        std::cout << "primary" << std::endl;
    }
};

template<typename T>
struct A<T, decltype(T().f())> {
    void operator()() {
        std::cout << "specialization" << std::endl;
    }
};

这样使用:

struct X {
    bool f() { return false; }
};

int main()
{
    A<X>()();
    return 0;
}

当人们期望选择部分特化时,主模板被解析。但是,当改为:

template<typename T>
struct A<T, typename std::enable_if<std::is_object<decltype(T().f())>::value>::type> {
    void operator()() {
        std::cout << "specialization" << std::endl;
    }
};

选择专业。为什么原始示例中没有选择专业化?

【问题讨论】:

  • @Rakete1111 我不认为这是重复的。该副本描述了一个格式错误的模板参数。这个问题涉及一个格式良好的专业化,它根本不专门化测试的使用。
  • 在我的“重新开放”投票之前等待看到“重新开放”投票或反驳...
  • @DrewDormann 无论如何这都没关系,但事实并非如此。副本提到了两者,并询问为什么没有为int 选择专业化。在这里,这是同一个问题:为什么即使表达式对给定类型有效,也没有选择特化。
  • 为了记录,this 是声称的副本。我会让群众决定,而不是试图客观。干杯!

标签: c++ templates sfinae template-specialization


【解决方案1】:

你已经实例化了:

A<X>

利用默认模板参数成为:

A<X,void>

但是,您的专长是:

template<typename T>
struct A<T, decltype(T().f())>

其中,对于模板参数X 变为:

struct A<X, decltype(X().f())>

这是:

struct A<X, bool>

因此,您的专业化不是正确的选择,因为A&lt;X,bool&gt; 不专业化A&lt;X,void&gt;。


如果您希望您的专业化适用于 所有 格式良好的 T().f() 实例,您可以使用 C++17 的 std::void_t

对于传递给它的任何个格式良好的模板参数,

std::void_t 将评估为 void。

template<typename T>
struct A<T, std::void_t<decltype(T().f())>> {
    void operator()() {
        std::cout << "specialization" << std::endl;
    }
};

【讨论】:

  • 似乎值得一提的是如何用 C++17 之前的东西来解决这个问题,即将,void() 添加到decltype 调用中,例如decltype(T().f(), void())
猜你喜欢
  • 2011-10-30
  • 1970-01-01
  • 2018-12-09
  • 2012-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多