non-template class 的模板构造函数的 C++ 显式实例化
C++ explicit instantiation of template constructor of non-template class
我正在研究使用 pimpl 习语的 C++ Fraction class,我的 public header 类似于(进行中)
Fraction.h
代码:
#pragma once
#include <memory>
#include <string>
class Fraction
{
public:
Fraction();
~Fraction();
template <typename N>
Fraction(N numerator, bool normalize = true);
template <typename N, typename D>
Fraction(N numerator, D denominator, bool normalize = true);
Fraction(Fraction&&);
Fraction& operator=(Fraction&&);
template <typename T>
bool operator==(T const & other);
template <typename T>
bool operator!=(T const & other);
std::string representation ();
private:
class impl;
std::unique_ptr<impl> pimpl;
};
我可以使用成员的显式实例化(例如比较运算符重载)在我的 cpp 文件中进行正确的特化
Fraction.cpp
部分代码
template <typename T>
bool Fraction::operator==(const T& other)
{
return pimpl->operator==(other);
}
template bool Fraction::operator==<int>(int const &);
template bool Fraction::operator==<float>(float const &);
template bool Fraction::operator==<double>(double const &);
template bool Fraction::operator==<Fraction>(Fraction const &);
但是当我想对构造函数做同样的事情时,我遇到了一些 VS2015 编译器错误:
template <typename N, typename D>
Fraction::Fraction(N num, D den, bool norm)
: pimpl{ std::make_unique<impl<N,D>>(num, den, norm) }
{}
template Fraction::Fraction<int, int>(int, int, bool);
我遇到构建错误(法语):
C2143 erreur de syntaxe : absence de ';' avant '<' fraction.cpp [156]
C2059 erreur de syntaxe : '<' fraction.cpp [156]
fraction.cpp 第 156 行是:
template Fraction::Fraction<int, int>(int, int, bool);
英文错误(近似翻译):
C2143 syntax error : absence of ';' before '<'
C2059 syntax error : '<'
我已经测试了显式实例化的一些变体,但找不到解决方案。我希望这是标准允许的?
EDIT:为了回答 Sam Varshavchik 的评论,cpp class 以以下形式集成了 Fraction class 的私有实现:
class Fraction::impl
{
public:
Fraction::impl()
: _num (0)
, _den (1)
{}
...
template <typename N, typename D>
Fraction::impl(N numerator, D denominator, bool normalize = true)
{
// TODO
}
...
};
在这里,不需要显式特化模板,因为它是 .hpp class 样式。
SOLUTION(感谢 Constructor
提供(如此明显的)解决方案)
template <typename N, typename D>
Fraction::Fraction(N num, D den, bool norm)
: pimpl{ std::make_unique<impl>(num, den, norm) }
{}
template Fraction::Fraction(int, int, bool);
刚刚:
- 将
impl<N,D>
替换为 impl
。
- 删除模板显式实例化中的
<int, int>
。
impl<N,D>
impl
不是模板,它是 class:
class impl;
看到了吗?这是一个声明 class。它不是一个模板,你的编译器理所当然地感到不安,因为你现在试图告诉它它是一个必须用两个模板参数实例化的模板,N
和 D
.
您的代码意图不明确,因此正确的操作过程并不明显。然而,另一个问题也很明显,这就在于你的未来:当你解决了你的编译错误之后,你会发现自己马上就盯着 link 失败,因为 templates can only be implemented in header files,而不是 .cpp
文件,就像你想做的那样。至少不是没有一些额外的工作。
在 C++ 中没有这样的语法来显式实例化模板构造函数:
template Fraction::Fraction<int, int>(int, int, bool);
^^^^^^^^^^
您应该改用以下简单语法:
template Fraction::Fraction(int, int, bool);
我正在研究使用 pimpl 习语的 C++ Fraction class,我的 public header 类似于(进行中)
Fraction.h
代码:
#pragma once
#include <memory>
#include <string>
class Fraction
{
public:
Fraction();
~Fraction();
template <typename N>
Fraction(N numerator, bool normalize = true);
template <typename N, typename D>
Fraction(N numerator, D denominator, bool normalize = true);
Fraction(Fraction&&);
Fraction& operator=(Fraction&&);
template <typename T>
bool operator==(T const & other);
template <typename T>
bool operator!=(T const & other);
std::string representation ();
private:
class impl;
std::unique_ptr<impl> pimpl;
};
我可以使用成员的显式实例化(例如比较运算符重载)在我的 cpp 文件中进行正确的特化
Fraction.cpp
部分代码
template <typename T>
bool Fraction::operator==(const T& other)
{
return pimpl->operator==(other);
}
template bool Fraction::operator==<int>(int const &);
template bool Fraction::operator==<float>(float const &);
template bool Fraction::operator==<double>(double const &);
template bool Fraction::operator==<Fraction>(Fraction const &);
但是当我想对构造函数做同样的事情时,我遇到了一些 VS2015 编译器错误:
template <typename N, typename D>
Fraction::Fraction(N num, D den, bool norm)
: pimpl{ std::make_unique<impl<N,D>>(num, den, norm) }
{}
template Fraction::Fraction<int, int>(int, int, bool);
我遇到构建错误(法语):
C2143 erreur de syntaxe : absence de ';' avant '<' fraction.cpp [156]
C2059 erreur de syntaxe : '<' fraction.cpp [156]
fraction.cpp 第 156 行是:
template Fraction::Fraction<int, int>(int, int, bool);
英文错误(近似翻译):
C2143 syntax error : absence of ';' before '<'
C2059 syntax error : '<'
我已经测试了显式实例化的一些变体,但找不到解决方案。我希望这是标准允许的?
EDIT:为了回答 Sam Varshavchik 的评论,cpp class 以以下形式集成了 Fraction class 的私有实现:
class Fraction::impl
{
public:
Fraction::impl()
: _num (0)
, _den (1)
{}
...
template <typename N, typename D>
Fraction::impl(N numerator, D denominator, bool normalize = true)
{
// TODO
}
...
};
在这里,不需要显式特化模板,因为它是 .hpp class 样式。
SOLUTION(感谢 Constructor
提供(如此明显的)解决方案)
template <typename N, typename D>
Fraction::Fraction(N num, D den, bool norm)
: pimpl{ std::make_unique<impl>(num, den, norm) }
{}
template Fraction::Fraction(int, int, bool);
刚刚:
- 将
impl<N,D>
替换为impl
。 - 删除模板显式实例化中的
<int, int>
。
impl<N,D>
impl
不是模板,它是 class:
class impl;
看到了吗?这是一个声明 class。它不是一个模板,你的编译器理所当然地感到不安,因为你现在试图告诉它它是一个必须用两个模板参数实例化的模板,N
和 D
.
您的代码意图不明确,因此正确的操作过程并不明显。然而,另一个问题也很明显,这就在于你的未来:当你解决了你的编译错误之后,你会发现自己马上就盯着 link 失败,因为 templates can only be implemented in header files,而不是 .cpp
文件,就像你想做的那样。至少不是没有一些额外的工作。
在 C++ 中没有这样的语法来显式实例化模板构造函数:
template Fraction::Fraction<int, int>(int, int, bool);
^^^^^^^^^^
您应该改用以下简单语法:
template Fraction::Fraction(int, int, bool);