在Rust中通过const泛型表达式约束trait

yrdbyhpb  于 2023-03-23  发布在  其他
关注(0)|答案(1)|浏览(154)

我试图更好地理解const泛型表达式,但我无法运行以下代码

trait Foo<const N: usize> {}

impl<const N: usize> Foo<{ N * N }> for () {}

因为
const参数N不受impl trait、self类型或 predicate 的约束
我也试过计算平方根编译时间,但是

trait Bar<const N: usize> {
    fn bar();
}

impl<const N: usize> Bar<N> for () {
    fn bar() {
        const L: i32 = 1 << N.ilog2();
    }
}

但我在N上遇到了一个问题
无法使用外部函数中的泛型参数
我不明白为什么第一个例子无法编译,因为Foo被N*N绑定,应该解析为一个数字。

f4t66c6m

f4t66c6m1#

首先,const泛型位置中的表达式只允许在夜间编译器和启用#![feature(generic_const_exprs)]的情况下使用,但即使这样,它仍然无法完全编译。
很可能只出现在表达式中的泛型永远不会被认为是受约束的,因为对于任意表达式,所施加的约束可能是不可能的,或者很难计算。
expanded explanation for E0207对这个具体的例子没有什么帮助,因为它根本没有讨论表达式。
你仍然可以通过简单地传递第二个const泛型作为一个dummy来实现类似的东西,它直接接收impl的泛型:

#![feature(generic_const_exprs)]
trait Bar<const N: usize, const M: usize> {
}

impl<const N: usize> Bar<N, {N*N}> for () {}

// just for demonstration purposes
fn print_bars<const N: usize, const M: usize>(_: impl Bar<N, M>) {
    println!("{N} {M}");
}

fn main() {
    print_bars::<2, 4>(());
    // print_bars::<2, 2>(()); // does not compile cause obviously this is not implemented by the above
}

相关问题