今天我的问题很简单:为什么编译器不能从类构造函数中推断模板参数,就像它可以从函数参数那样做?例如,为什么以下代码无效:
template<typename obj>
class Variable {
obj data;
public: Variable(obj d)
{
data = d;
}
};
int main()
{
int num = 2;
Variable var(num); //would be equivalent to Variable<int> var(num),
return 0; //but actually a compile error
}
Run Code Online (Sandbox Code Playgroud)
正如我所说,我明白这是无效的,所以我的问题是为什么不是呢?允许这会产生任何重大的句法漏洞吗?是否存在不希望使用此功能的实例(推断类型会导致问题)?我只是想了解允许函数的模板推理背后的逻辑,但不适用于适当构造的类.
假设我有一个包含值的LimitedValue类,并在int类型'min'和'max'上进行参数化.您可以将它用作容纳值的容器,该值只能在一定范围内.你可以使用它:
LimitedValue< float, 0, 360 > someAngle( 45.0 );
someTrigFunction( someAngle );
Run Code Online (Sandbox Code Playgroud)
这样'someTrigFunction'知道它可以保证提供有效的输入(如果参数无效,构造函数会抛出异常).
但是,复制构造和分配仅限于完全相同的类型.我希望能够做到:
LimitedValue< float, 0, 90 > smallAngle( 45.0 );
LimitedValue< float, 0, 360 > anyAngle( smallAngle );
Run Code Online (Sandbox Code Playgroud)
并在编译时检查该操作,因此下一个示例给出了一个错误:
LimitedValue< float, -90, 0 > negativeAngle( -45.0 );
LimitedValue< float, 0, 360 > postiveAngle( negativeAngle ); // ERROR!
Run Code Online (Sandbox Code Playgroud)
这可能吗?是否有一些实际的方法可以做到这一点,或者有哪些例子可以解决这个问题?
如果可以为编译器做的话,我正在寻找一种在编译时检查函数参数的方法.
更具体一点:假设我们有一些类Matrix.
class Matrix
{
int x_size;
int y_size;
public:
Matrix(int width, int height):
x_size{width},
y_size{height}
{}
Matrix():
Matrix(0, 0)
{}
};
int main()
{
Matrix a; // good.
Matrix b(1, 10); // good.
Matrix c(0, 4); // bad, I want compilation error here.
}
Run Code Online (Sandbox Code Playgroud)
那么,在传递给函数的静态(源编码)值的情况下,我可以检查或区分行为(函数重载?)?
如果值不是静态的:
std::cin >> size;
Matrix d(size, size);
Run Code Online (Sandbox Code Playgroud)
我们只能做运行时检查.但是如果值在源代码中编码?在这种情况下我可以进行编译时检查吗?
编辑:我认为这可以通过constexpr构造函数实现,但无论如何都不允许使用和不使用constexpr进行重载.所以问题无法以我想象的方式解决.