[英]Declare member function only on specific specialization of templated class
I have a templated class to aid in compile time computation of physical quantities.我有一个模板类来帮助物理量的编译时计算。 It uses the extra template parameters (
std::ratio
) to ensure things like a Length
can only be added to a Length
, or that Area
is a Length
times a Length
.它使用额外的模板参数(
std::ratio
)来确保只能将Length
之类的内容添加到Length
中,或者Area
是Length
乘以Length
。
#include <ratio>
template <
typename Length = std::ratio<0>, // Meter
typename Mass = std::ratio<0>, // Kilogram
typename Time = std::ratio<0>, // Second
typename Current = std::ratio<0>, // Ampere
typename Temperature = std::ratio<0>, // Kelvin
typename Amount = std::ratio<0>, // Mole
typename Luminous = std::ratio<0> // Candela
>
class Quantity {
private:
double value;
public:
constexpr Quantity(double val) : value(val) {}
Quantity &operator+=(Quantity const &that) {
value += that.value;
return *this;
}
// ...
};
But sometimes I want to convert back to a simple double
, for interfacing with other stuff.但有时我想转换回一个简单的
double
,以便与其他东西交互。
I could add a member function for the templated class that returns the internal double
- or enables implicit (or explicit) conversion to double
when a double
is needed.我可以为返回内部
double
精度的模板类添加一个成员函数 - 或者在需要double
精度时启用隐式(或显式)转换为double
精度。
constexpr double getValue() { return value; }
constexpr operator double() { return value; }
However, I really only want this implicit conversion to happen when the "dimensions" of the quantity are all 0 (all template parameters are 0).但是,我真的只希望在数量的“维度”全部为 0(所有模板参数为 0)时发生这种隐式转换。
I could just declare the same member functions and only define the specialization that I want.我可以只声明相同的成员函数,只定义我想要的特化。 But that still declares that the conversion exists for types that I don't ever want to allow conversion from (you should divide by your desired units first).
但这仍然声明对于我不想允许转换的类型存在转换(您应该首先除以所需的单位)。 This makes my editor tell me it's ok but it won't link at compiletime.
这让我的编辑告诉我没关系,但它不会在编译时链接。
Is there a way to declare member functions only on certain specializations?有没有办法只在某些特化上声明成员函数?
Of note, I'm stuck on C++14 for now, otherwise I think an if constexpr
could work...值得注意的是,我现在坚持使用 C++14,否则我认为
if constexpr
可以工作......
No, if constexpr
cannot be used to provide for conditional definition of class methods.不,
if constexpr
不能用于提供类方法的条件定义。 if constexpr
belongs in some method or a function, so that needs to be declared before anything can be done with if constexpr
, and your goal is to not even declare it in the first place. if constexpr
属于某个方法或函数,因此需要先声明它,然后才能使用if constexpr
完成任何操作,而您的目标甚至是一开始就不要声明它。
There is no way to directly instantiate a class method only for certain specializations or template instances, however there's a common approach that comes pretty close: simulate an overload resolution failure.没有办法只为某些特化或模板实例直接实例化类方法,但是有一种非常接近的通用方法:模拟重载解析失败。
Here's a simplified example:这是一个简化的示例:
#include <type_traits>
#include <iostream>
template<typename T>
struct life {
template<typename=
typename std::enable_if<std::is_same<T,int>::value>::type>
constexpr int answer()
{
return 42;
}
};
int main()
{
life<int> of_brian;
std::cout << of_brian.answer() << std::endl; // Shows 42
life<double> of_black_night;
std::cout << of_black_night.answer() << std::endl; // Error
return 0;
}
The template class effectively implements answer()
only for its int
instance.模板类仅对其
int
实例有效地实现answer()
。 gcc
's error message, for attempting to invoke it from an undesirable instance of the template is: gcc
的错误消息,用于尝试从不需要的模板实例调用它是:
error: no matching function for call to 'life<double>::answer()'
错误:没有匹配函数调用 'life<double>::answer()'
which is a pretty close facsimile for "this doesn't exist, pal".这是“这不存在,伙计”的非常接近的传真。
This is logically equivalent to what you're attempting to do with your template, the only difference is that you need to check a bunch of template parameters, instead of just one.这在逻辑上等同于您尝试对模板执行的操作,唯一的区别是您需要检查一堆模板参数,而不仅仅是一个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.