英文:
Confusion about template parameters
问题
-
template
in C++ is designed to be flexible and can work with both type parameters and non-type parameters (such as values or objects) based on how it's declared. In your examples,template<typename A>
andtemplate<int v, Unit u>
are templates with type and non-type parameters, respectively. When you define a template, you specify the kind of parameters it accepts.In the case of
Measure_add
,M1
andM2
are indeed types (they are expected to be types likeMeasure<int, Unit::m>
), but they have a membervalue
which is a constant expression. This allows you to accessM1::value
andM2::value
. This usage is allowed because you've defined theMeasure
struct with these member variables. -
Accessing
M1::value
andM2::value
in the template structMeasure_add
is possible because you've constrained the template parametersM1
andM2
to be types that have thevalue
member variable. If you were to use other parameters that don't contain thevalue
attribute, it would indeed cause a compilation error because the compiler wouldn't find thevalue
member in those types. So, the code is designed to work specifically with types that have the expected member attributes, and it enforces this constraint through the template parameter types.
英文:
Lately I practiced the use of template
in c++, and I am confused about one of the template parameters during the process.
For instance, in the following code, the input A
of template<typename A>
served as a 'type' to construct function and variables.
template <typename A>
A add_simple(A a, A b)
{
return a + b;
}
However, in the following example, a unit conversion operation, it seems the input M1
and M2
serve as objects. In main()
, I've shown how the struct is expected to be called.
// create a template struct Measure with value and unit. e.g. Measure<int, Unit>::value
template<int v, Unit u> struct Measure{
static const int value=v;
static const Unit unit=u;
};
// Conversion struct. expected input two 'Measure' objects.
template <typename M1, typename M2>
struct Measure_add {
public:
// other implementation
static constexpr int value=M1::value+M2::value;
};
int main(int, char**) {
std::cout << Measure_add< Measure<10,Unit::m>,
Measure<20,Unit::m> >::value << std::endl;
}
So my confusion about template is:
-
Is
<template>
designed to be such flexible that it dynamically distinguish the input so both a 'type' input and 'object' input works. Or the difference met here because the expected inputs are constructed template inputMeasure
? As a result, M1 and M2 are still 'type',Measure
. And in this case, whyM1::value
is available if M1 is a type instead of an object? -
Why is it available to get access to
M1::value
orM2::value
in template structMeasure_add
though the inputs are unknown to such struct. In other words, if I input other parameters which don't contain attributevalue
, would it cause problem?
答案1
得分: 1
在你的代码中,`M1` 和 `M2` 都是类型模板参数。你可以说 `M::value` 的原因是 `value` 是在类型 `M` 中被替换的静态数据成员。这就是 `static` 数据成员的要点:你不需要一个对象来访问它的值。这与模板无关:
```cpp
struct M {
static constexpr int value = 0;
};
int foo() {
return M::value; // 可行
}
M1
和 M2
不受限于作为 Measure
模板的特化:它们可以是任何具有静态 value
数据成员的类型。对于不满足此条件的其他类型,你将会得到一个编译错误。
std::cout <<
Measure_add<
std::integral_constant<int, 10>,
std::integral_constant<int, 20>
>::value; // 编译通过,输出 30
以及
std::cout <<
Measure_add<
Measure<10, Unit::m>,
std::integral_constant<int, 20>
>::value; // 编译通过,输出 30,但没有意义
<details>
<summary>英文:</summary>
In your code both `M1` and `M2` are type template parameters. The reason why you can say `M::value` is that `value` is a static data member in a type that is substituted for `M`. That's the point of a `static` data member: you don't need an object to access its value. This is not related to templates:
struct M {
static constexpr int value = 0;
};
int foo() {
return M::value; // OK
}
`M1` and `M2` are not constrained to being specializations of `Measure` template: they can be any types that have a static `value` data member. For other types that don't satisfy this condition you'll simply get a compilation error.
std::cout <<
Measure_add<
std::integral_constant<int, 10>,
std::integral_constant<int, 20>
>::value; // compiles, prints 30
and
std::cout <<
Measure_add<
Measure<10, Unit::m>,
std::integral_constant<int, 20>
>::value; // compiles, prints 30, but makes no sense
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论