3

这个问题是基于安德烈对我关于签名约束的问题的回答。

struct S(int x, int y) {
  void fun(T)(T t) if (is(T U == S!(a, b), int a, int b)) { }
}

template s(int a, int b) {
  enum result = S!(a,b)();
  alias result s;
}

void main() {

  auto s1 = S!(1, 1)();
  auto s2 = S!(2, 2)();
  auto s3 = s!(3, 3);
  auto s4 = s!(4, 4);

  s1.fun(s1);  // ok
  s1.fun(s2);  // ok
  s1.fun(s3);  // compile error
  s3.fun(s1);  // ok
  s3.fun(s3);  // compile error
  s3.fun(s4);  // compile error
}

我不明白为什么代码会产生编译错误。有任何想法吗?

4

1 回答 1

3

首先,我不建议使用裸模板来生成对象/结构的实例,因为您本质上要求该对象能够进行 CTFE。如果您需要一个实例,最好的选择是return从模板函数中获得它:

@property S!(a, b) s(int a, int b)()
{
    return S!(a, b)();
}

但是,这似乎仍然不适用于模板约束。我认为这必须是一个前端错误。据我所知,返回的类型似乎无法在 is() 表达式中正确检查,除非它已经在其他地方实例化,例如:

struct S(int x, int y) 
{
    void fun(T)(T t) 
        if (is(T U == S!(a, b), int a, int b))
    {

    }
}

@property S!(a, b) s(int a, int b)()
{
    return S!(a, b)();
}

void main() 
{
    auto s1 = S!(1, 1)();
    auto s2 = S!(2, 2)();  // comment out and you get errors in fun() call
    auto s3 = s!(2, 2);
    s1.fun(s3);
}

我会将此作为错误提交。

编辑:归档为问题 8493

于 2012-08-02T14:40:46.033 回答