使用依赖类型的模板构造函数的专用模板类(来自一般情况)

时间:2016-02-17 16:56:34

标签: c++ templates

我需要使一个模板化的类构造函数采用依赖类型(在模板化的类类型上)。这工作正常,除非我有模板化类的特化,在这种情况下似乎找不到构造函数。如果我重新实现专用子类中的构造函数,我似乎无法通过构造函数或直接初始化基类。

有没有办法在班级之外保留这个相对狭窄的界面?

class T1 {};
class T2 {};

// KeyType
template <typename SELECT>
class KeyType {
};

// Declarations
template <typename SELECT = T1>
class TestTemplate {
protected:
    TestTemplate() {}
    KeyType<SELECT> k;
public:
    TestTemplate(KeyType<SELECT> const &key) : k(key) {}
};

template <>
class TestTemplate<T2> : public TestTemplate<T1> {
};


int main() {

    KeyType<T2> key;
    TestTemplate<T2> foo(key);
    return 0;
}

在稍微盯着它之后,我意识到问题在于我不能随意将KeyType<T2>转换为KeyType<T1> TestTemplate<T1>基类。{ / p>

g ++给出:

g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In function 'int main()':
main.cpp:27:29: error: no matching function for call to 'TestTemplate<T2>::TestTemplate(KeyType<T2>&)'
     TestTemplate<T2> foo(key);
                             ^
main.cpp:20:7: note: candidate: TestTemplate<T2>::TestTemplate()
 class TestTemplate<T2> : public TestTemplate<T1> {
       ^
main.cpp:20:7: note:   candidate expects 0 arguments, 1 provided
main.cpp:20:7: note: candidate: constexpr TestTemplate<T2>::TestTemplate(const TestTemplate<T2>&)
main.cpp:20:7: note:   no known conversion for argument 1 from 'KeyType<T2>' to 'const TestTemplate<T2>&'
main.cpp:20:7: note: candidate: constexpr TestTemplate<T2>::TestTemplate(TestTemplate<T2>&&)
main.cpp:20:7: note:   no known conversion for argument 1 from 'KeyType<T2>' to 'TestTemplate<T2>&&'

1 个答案:

答案 0 :(得分:1)

构造函数在C ++中根本不是继承的,因此您的实例TestTemplate<T2>只有隐式声明的构造函数(默认,复制并通过您发布的错误消息移动它)。如果您认为,当您专门化模板时,专用模板会从专用模板继承声明和定义:情况并非如此。您必须重新声明并重新定义专用模板中的所有成员。

因此,在您的情况下,您必须将适当的构造函数添加到您的专用模板中,如下所示:

template <>
class TestTemplate<T2> : public TestTemplate<T1> {
public:
    TestTemplate<KeyType<T2> const &key) :
    TestTemplate<T1>(...) {}
};

由于基类TestTemplate<T1>不提供默认构造函数,因此必须调用该构造函数,但是,由于您有引用,因此不清楚要将其作为键参数传递给它到KeyType<T2>而不是KeyType<T1>的实例。

如果您希望从TestTemplate<T1>继承构造函数,可以使用using指令执行此操作,假设您使用的是C ++ 11:

template <>
class TestTemplate<T2> : public TestTemplate<T1> {
public:
    using TestTemplate<T1>::TestTemplate;
};

但诚然,我不是100%关于这里的语法。