Thread overview | ||||||
---|---|---|---|---|---|---|
|
July 08, 2020 How to ensure template function can be processed during compile time | ||||
---|---|---|---|---|
| ||||
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? |
July 08, 2020 Re: How to ensure template function can be processed during compile time | ||||
---|---|---|---|---|
| ||||
Posted in reply to IGotD- | 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! |
July 08, 2020 Re: How to ensure template function can be processed during compile time | ||||
---|---|---|---|---|
| ||||
Posted in reply to IGotD- | 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);
|
July 08, 2020 Re: How to ensure template function can be processed during compile time | ||||
---|---|---|---|---|
| ||||
Posted in reply to IGotD- | 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);
|
Copyright © 1999-2021 by the D Language Foundation