如何在之前声明的另一个模板参数中使用模板参数

发布于 2024-08-06 01:14:09 字数 881 浏览 10 评论 0原文

模板参数可以在其后的另一个模板参数中使用,如下所示:

template<typename T, T N>
struct s
{
};

但是如果在“N”之后声明“T”,是否可以引用“T”?

这不起作用:

template<T N, typename T>
struct s
{
};

我们可以通过预先声明“T”或做其他事情来帮助编译器吗?

提前致谢。

编辑:正如前两个回复问“你为什么愿意这样做?”我将解释目标:

我想让编译器推断出类型“T”,以便更轻松地使用模板化类。

例如:

template<typename T, T A, T B>
struct sum
{
    static T const value = A + B;
};

这个模板可以这样使用:

sum<int, 1, 2>::value

但是如果可以这样使用那就更好了:

sum<1, 2>::value

从技术上讲,它应该是可能的,因为编译器知道“1”和“2”的类型:“int”,并且在事实上,它使用这些信息来找到函数的最佳重载。 因此,通过这样声明模板:

template<T A, T B, typename T>
struct sum
{
    static T const value = A + B;
};

编译器可以利用其功能从第一个和第二个参数提供的信息推断最后一个参数,然后找到最佳模板进行实例化。

a template parameter can be used in another template parameter that follows it this way :

template<typename T, T N>
struct s
{
};

But is it possible to reference "T" if it is declared after "N" ?

This does not work :

template<T N, typename T>
struct s
{
};

Can we help the compiler by pre-declaring "T" or doing anything else ?

Thanks by advance.

EDIT : as the first two replies were asking "why are you willing to do that ?" I'll explain the goal :

I would like to make the compiler infer the type "T" in order to make the use of templated classes easier.

For example :

template<typename T, T A, T B>
struct sum
{
    static T const value = A + B;
};

This template can be used this way :

sum<int, 1, 2>::value

But it would be better if it could be used this way :

sum<1, 2>::value

Technically it's should be possible because the compiler knows the types of "1" and "2" : "int", and in fact it uses these informations to find the best overload for a function.
So by declaring the template this way :

template<T A, T B, typename T>
struct sum
{
    static T const value = A + B;
};

the compiler could use its capability to infer the last parameter from the informations provided by the first and the second one, and then find the best template to instantiate.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

烈酒灼喉 2024-08-13 01:14:09

就像其他人说的那样 - 不,这是不可能的,编译器无法从非类型 template 参数中推断出 T 的类型(在函数的情况下,它从函数参数推断类型):

14.8.2.4/12

无法从非类型模板参数的类型推导出模板类型参数。

无论如何,不​​会对类模板的参数进行任何扣除。函数模板的一个示例可能是

template<int> struct having_int { };
template<typename T, T i> void f(having_int<i>);
int main() { having_int<0> h; f(h); }

在这种情况下,T 不会被推导为 int - 您必须显式指定它。

Like others say - No this isn't possible, the compiler can't infer the type of T from the non-type template arguments (in the case of functions, it infers types from the function arguments):

14.8.2.4/12:

A template type argument cannot be deduced from the type of a non-type template-argument.

In any case, no deduction will be made for the arguments of a class template anyway. An example for a function template might be

template<int> struct having_int { };
template<typename T, T i> void f(having_int<i>);
int main() { having_int<0> h; f(h); }

In this case, T won't be deduced as int - you have to explicitly specify it.

风筝在阴天搁浅。 2024-08-13 01:14:09

你不能。我不明白你为什么这样做。

You can't. I don't see the point why you are doing it too.

紫瑟鸿黎 2024-08-13 01:14:09

下面是垃圾,因为我没有正确阅读你的问题。

事实上,我也不认为你想要实现的目标有任何意义。

#include <iostream>

template<typename T, T N>
struct s
{
    T size() { return N; }
};


int main()
{
    s<int, 4> x;
    std::cout << x.size()<< '\n';

    //s<float, 3.14> f; //this doesn't compile
}

这可以通过 GCC 和 Comeau Online 进行编译。

我认为问题在于您尝试使用的 T 类型。非类型模板参数仅支持整型,然后是指向具有外部链接的对象的指针(或类似的东西,也许还有其他一些非常有限的东西)。

Below is rubbish as I didn't read your question properly.

Indeed, I don't see any point in what you are trying to achieve either.

#include <iostream>

template<typename T, T N>
struct s
{
    T size() { return N; }
};


int main()
{
    s<int, 4> x;
    std::cout << x.size()<< '\n';

    //s<float, 3.14> f; //this doesn't compile
}

This compiles for me with GCC and Comeau Online.

I think the problem is with the type of T you are trying to use. Non-type template arguments only support integral types, and then pointers to objects with external linkage (or something like that and perhaps a few other very limited things).

梦一生花开无言 2024-08-13 01:14:09

你可以用 C++17 来做到这一点

template <auto n>
struct s;

template <typename T, T n>
struct s<n>
{
    static constexpr T threshold = n;
    bool above_threshold(T x) { return x > threshold; }
};

,然后你就可以做到

void some_fn(int x)
{
    s<18> my_s;
    if (my_s.above_threshold(x)) { /*...*/ }
}

You can do this with C++17

template <auto n>
struct s;

template <typename T, T n>
struct s<n>
{
    static constexpr T threshold = n;
    bool above_threshold(T x) { return x > threshold; }
};

and then you'll be able to do

void some_fn(int x)
{
    s<18> my_s;
    if (my_s.above_threshold(x)) { /*...*/ }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文