www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to ensure template function can be processed during compile time

reply IGotD- <nise nise.com> writes:
I have the following functions in C++

template<typename T>
inline constexpr size_t mySize(const T &v)
{
     return sizeof(v) + 42;
}


template<typename T>
inline constexpr size_t mySize()
{
     return sizeof(T) + 42;
}

The constexpr ensures that it will be calculated to a compile 
time constant otherwise the build will fail. In this case C++ can 
handle that I feed these functions with both a type and a 
variable which it can solve during compile time.

int v;

constexpr size_t sz = mySize(v);       // works, returns 46
constexpr size_t sz2 = mySize<int>();  // works, returns 46


Doing the same in D, would with my lack of knowledge look like 
this.


size_t mySize(T)()
{
     return T.sizeof + 42;
}


size_t mySize(T)(const T t)
{
      return T.sizeof + 42;
}



int v;

enum sz = mySize!int // works, returns 46
enum sz2 = mySize(v) // doesn't work. Error: variable v cannot be 
read at compile time

Here we have a difference between C++ and D as C++ was able infer 
the size of v during compile time.

Now since mySize is a template, shouldn't this work mySize!v, but 
it doesn't? What essential understanding have I missed here?
Jul 08 2020
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Jul 08, 2020 at 08:11:05PM +0000, IGotD- via Digitalmars-d-learn wrote:
[...]
 Doing the same in D, would with my lack of knowledge look like this.
 
 
 size_t mySize(T)()
 {
     return T.sizeof + 42;
 }
What you want is: enum mySize(T) = T.sizeof + 42; And there is no need for a const overload. [...]
 int v;
 
 enum sz = mySize!int // works, returns 46
 enum sz2 = mySize(v) // doesn't work. Error: variable v cannot be read at
 compile time
Yes, because you're trying to pass the value of a variable to mySize, and that variable doesn't have a value until runtime.
 Here we have a difference between C++ and D as C++ was able infer the
 size of v during compile time.
 
 Now since mySize is a template, shouldn't this work mySize!v, but it
 doesn't? What essential understanding have I missed here?
https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time T -- The diminished 7th chord is the most flexible and fear-instilling chord. Use it often, use it unsparingly, to subdue your listeners into submission!
Jul 08 2020
prev sibling next sibling parent Max Samukha <maxsamukha gmail.com> writes:
On Wednesday, 8 July 2020 at 20:11:05 UTC, IGotD- wrote:

 Now since mySize is a template, shouldn't this work mySize!v, 
 but it doesn't? What essential understanding have I missed here?
You are trying to use a run-time value of v at compile-time, which is not possible. If you want the modified size of the type of a variable, you can pass the variable to the compile-time function by alias: enum mySize(alias e) = e.sizeof + 42; int v; enum size = mySize!v; pragma(msg, size); // 46LU If you want to the size of the type of a run-time expression, you will have to use typeof: static assert(mySize!(typeof(v + 1)) == 46);
Jul 08 2020
prev sibling parent Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Wednesday, 8 July 2020 at 20:11:05 UTC, IGotD- wrote:

 int v;

 enum sz = mySize!int // works, returns 46
 enum sz2 = mySize(v) // doesn't work. Error: variable v cannot 
 be read at compile time

 Here we have a difference between C++ and D as C++ was able 
 infer the size of v during compile time.
To add to other respondents' replies, you can pass something that is known at compile time, for example the .init value: int v; enum sz2 = mySize(v.init); static assert(sz2 == 46); This way the compiler is able to evaluate `mySize` at compile time. Or use an alias template argument: auto mySize(alias v)() { return v.sizeof + 42; } int v; enum sz = mySize!int; enum sz2 = mySize!v; static assert(sz == sz2); static assert(sz == 46);
Jul 08 2020