Thread overview
Is there a way to initialize a non-assigned structure declaration (or is it a definition)?
Nov 09, 2012
Ali Çehreli
Nov 10, 2012
Era Scarecrow
Nov 10, 2012
Nick Sabalausky
Nov 13, 2012
Vijay Nayar
November 09, 2012
struct Parameterized(T, U, V, W)
{
   T t;
   U u;
   V v;
   W w;
   this(T t, U u, V v, W w)
   {
      this.t = t;
	  this.u = u;
	  this.v = v;
	  this.w = w;
   }
}

Parameterized!(int, double, bool, char) p1; // compiles
// or
auto p2 = Parameterized!(int, double, bool, char)();  // must have the empty () to compile
// or
auto p3 = Parameterized!(int, double, bool, char)(57, 7.303, false, 'Z');  // compiles
// but not
// Parameterized!(int, double, bool, char)(93, 5.694, true, 'K')  p4;
// Error: found 'p4' when expecting ';' following statement
// nor
// Parameterized!(int, double, bool, char)  p5(93, 5.694, true, 'K');
// Error: found 'p5' when expecting ';' following statement
// nor, OK this was a crazy try
// Parameterized!(int 93, double 5.694, bool true, char 'K')  p6;
// Error: found '93' when expecting '.' following int
November 09, 2012
On 11/09/2012 03:35 PM, Too Embarrassed To Say wrote:
> struct Parameterized(T, U, V, W)
> {
> T t;
> U u;
> V v;
> W w;
> this(T t, U u, V v, W w)
> {
> this.t = t;
> this.u = u;
> this.v = v;
> this.w = w;
> }
> }

You are obviously using this just as an example but I wanted say that you don't need a constructor because structs provide an automatic one that copies the arguments to the members one by one.

> Parameterized!(int, double, bool, char) p1; // compiles
> // or
> auto p2 = Parameterized!(int, double, bool, char)(); // must have the
> empty () to compile
> // or
> auto p3 = Parameterized!(int, double, bool, char)(57, 7.303, false,
> 'Z'); // compiles

That is my preference.

> // but not
> // Parameterized!(int, double, bool, char)(93, 5.694, true, 'K') p4;
> // Error: found 'p4' when expecting ';' following statement
> // nor

I don't expect that to work; the arguments must go after the variable there.

> // Parameterized!(int, double, bool, char) p5(93, 5.694, true, 'K');
> // Error: found 'p5' when expecting ';' following statement

Ok, that is strange. I don't understand what "statement" the compiler sees there.

> // nor, OK this was a crazy try
> // Parameterized!(int 93, double 5.694, bool true, char 'K') p6;
> // Error: found '93' when expecting '.' following int

No, that shouldn't work.

There is also the common idiom of providing a convenience function to help with template parameter deduction:

auto parameterized(T, U, V, W)(T t, U u, V v, W w)
{
    return Parameterized!(T, U, V, W)(t, u, v, w);
}

/* ... */

    auto p7 = parameterized(93, 5.5, true, 'K');

Ali

November 10, 2012
On Friday, 9 November 2012 at 23:57:35 UTC, Ali Çehreli wrote:
> On 11/09/2012 03:35 PM, Too Embarrassed To Say wrote:
>> // Parameterized!(int, double, bool, char) p5(93, 5.694, true, 'K');
>> // Error: found 'p5' when expecting ';' following statement
>
> Ok, that is strange. I don't understand what "statement" the compiler sees there.

 Let's alias the above to simplify...

 alias Parameterized!(int,double,bool,char) Param;

 Param p5(93, 5.694, true, 'K');

 As it looks, it appears you are either confusing it with a function declaration, or it's trying to call p5(doesn't exist), or pre-initialize p5 the wrong way.
November 10, 2012
On Sat, 10 Nov 2012 00:35:05 +0100
"Too Embarrassed To Say" <kheaser@eapl.org> wrote:
>
> auto p3 = Parameterized!(int, double, bool, char)(57, 7.303,
> false, 'Z');  // compiles
> // but not
> // Parameterized!(int, double, bool, char)(93, 5.694, true, 'K')
> p4;

That's as expected. Variable declarations are of the form:

    Type varName;
    // or
    Type varName = initialValue;

(In the second form, "auto" is optionally allowed to stand in for the
type.)

And struct literals (ie the actual values of a struct type) are of the
form:

    Type(params)

So:

- Parameterized is a template
- Parameterized!(int, double, bool, char) is a type.
- Parameterized!(int, double, bool, char)(93, 5.694, true, 'K') is a
*value* of the above type, it's *not* a type.

So when you say:

    Parameterized!(int, double, bool, char)(93, 5.694, true, 'K') p4;

That's a value, not a type. So that's just like saying:

    5 myInt;
    // or
    "Hello" myStr;

Which doesn't make sense. What you wanted to say was:

    int myInt = 5;
    // or
    auto myInt = 5;
    // or
    string myStr = "hello";
    // or
    auto myStr = "hello";

Therefore, you have to say:

    auto p3 = Parameterized!(int, double, bool, char)(93, 5.694, true,
    'K');

Because *that* is of the form: Type varName = initialValue;

If you want an easier way to do it, you can do this:

    alias Parameterized!(int, double, bool, char) MyType;
    auto p3 = MyType(93, 5.694, true, 'K')

Or, like Ali said, you can make a convenience function.

November 10, 2012
I appreciate all the helpful replies, but I've simplified things to what I belive is the core issue. In C++ (at the risk of becoming a heretic) the language allows me to do the following:

struct SnonParameterized
{
public:
   int t;
   float u;
   SnonParameterized(int tparam, float uparam);
};

SnonParameterized::SnonParameterized(int tparam, float uparam)
{
   t = tparam;
   u = uparam;
}

SnonParameterized snp(5, 3.303);  // this compiles with Visual C++ 2010


===============================================================================

Now with D, I try (what I think is identical semantics) the following:


struct SnonParameterized
{
   int t;
   float u;
   this(int t, float u)
   {
      this.t = t
      this.u = u;
   }
}

SnonParameterized cnp(5, 3.303);  // fails compile with Error: found 'cnp' when expecting ';' following statement

auto hi = SnonParameterized(5, 3.303);  // compiles of course.


I'm just trying to understand why D disallows the non-assignment syntax.  Probably for a very good (and obvious) reason.

November 13, 2012
This is merely a syntactic difference in how structs are handled.  In D, structs are more akin to low level types like int and have most of the same symantics.

So
  SnonParameterized cnp(5, 3.303);
makes about as much sense as
  int cnp(3);

You have two syntax choices to pick from in the D version of the code you posted:
  struct SnonParameterized
  {
    int t;
    float u;
  };

  void main() {
    auto snon1 = SnonParameterized(3, 4.5);  // Option 1
    SnonParameterized snon2 = {3, 4.5};      // Option 2
  }

 - Vijay


On Saturday, 10 November 2012 at 17:41:00 UTC, Too Embarrassed To Say wrote:
> I appreciate all the helpful replies, but I've simplified things to what I belive is the core issue. In C++ (at the risk of becoming a heretic) the language allows me to do the following:
>
> struct SnonParameterized
> {
> public:
>    int t;
>    float u;
>    SnonParameterized(int tparam, float uparam);
> };
>
> SnonParameterized::SnonParameterized(int tparam, float uparam)
> {
>    t = tparam;
>    u = uparam;
> }
>
> SnonParameterized snp(5, 3.303);  // this compiles with Visual C++ 2010
>
>
> ===============================================================================
>
> Now with D, I try (what I think is identical semantics) the following:
>
>
> struct SnonParameterized
> {
>    int t;
>    float u;
>    this(int t, float u)
>    {
>       this.t = t
>       this.u = u;
>    }
> }
>
> SnonParameterized cnp(5, 3.303);  // fails compile with Error: found 'cnp' when expecting ';' following statement
>
> auto hi = SnonParameterized(5, 3.303);  // compiles of course.
>
>
> I'm just trying to understand why D disallows the non-assignment syntax.  Probably for a very good (and obvious) reason.