【问题标题】:Explicit template specialization & dependent name lookup problems显式模板专业化和依赖名称查找问题
【发布时间】:2014-01-13 21:27:01
【问题描述】:

我正在尝试编写一个具有部分和显式专业化的类。虽然名称查找怪癖有问题。现在我有:

template <typename C, typename R>
class Command {
public:
    Command();

private:
void doTheDew() {
    /* ... */
}
};

template <typename C, typename R>
Command<C, R>::Command() {
    doTheDew();
}

template<typename R>
class Command<void, R> {
public:
    Command() {
        this->doTheDew();
    }
};

template<typename C>
class Command<C, void> {
public:
    Command() {
        this->doTheDew();
    }
};

template<>
class Command<void, void> {
public:
    Command() {
        this->doTheDew(); // 1
    }
};

在标有“1”的行上出现错误

class Command<void, void> has no member named doTheDew

在这一点上我已经尝试了很多,但不明白我错过了什么。

【问题讨论】:

  • 每个部分特化都是它自己的类。您需要提供doTheDew的各自定义
  • 也许我搞砸了术语,但部分专业化似乎有效(我需要 this 取消引用,否则我会遇到名称查找错误)。这只是我遇到问题的明确专业化。

标签: c++ templates


【解决方案1】:

它在标记为// 1 的行中立即失败,但在其他两个特化中它也在实例化时失败。

Command<int,void> c1; // fail
Command<void,int> c2; // fail
Command<int,int> c3; // OK

Live example

原因是没有一个特化有doTheDew() 方法,因为每个特化都是有自己的成员的自己的类。

您可能会考虑将应可用于主模板和所有特化的方法移至基类。然后不要忘记从该基础派生主模板和专业化。

【讨论】:

    【解决方案2】:

    正如 0x499602D2 指出的那样,模板只是用来生成类的模板。所以每个模板特化都是一个不同的类。您需要在所有专业中提供doTheDew 声明/定义。

    减少代码重复的一种方法是创建一个提供doTheDew 方法的基类,并让所有特化都继承自它:

    struct dothedew_impl
    {
        void doTheDew();
    };
    
    template<typename C>
    class Command<C, void> : public dothedew_impl
    {
    public:
        Command() {
            this->doTheDew();
        }
    };
    

    当然,如果doTheDew()方法依赖于类的某个模板参数,你也可以将基类设为模板:

    template<typename T>
    struct dothedew_impl
    {
        void doTheDew();
    };
    
    template<typename C>
    class Command<C, void> : public dothedew_impl<C>
    {
    public:
        Command() {
            this->doTheDew();
        }
    };
    

    请注意,最后一个Command() 实现示例中的this-&gt; 是必需的,因为template dependent names are resolved during second template parsing phasethis-&gt; 用于强制编译器将doTheDev() 包含在类作用域中,并将其移至第一阶段。

    【讨论】:

      猜你喜欢
      • 2013-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-26
      • 2018-09-28
      • 2015-06-12
      相关资源
      最近更新 更多