6

Header.h

template <int>
class FiniteElement {
public:
    int GetDOF();
};

using FiniteElement2D = FiniteElement<3>;
using FiniteElement3D = FiniteElement<6>;

Source.cpp

#include "Header.h"

//template class FiniteElement<3>;
//template class FiniteElement<6>;
template FiniteElement2D;  // Using alias for explicit template instantiation !!!
template FiniteElement3D;

template <int DOF>
int FiniteElement<DOF>::GetDOF() {
    return DOF;
}

Main.cpp

#include "Header.h"
#include <iostream>

int main() {
    FiniteElement3D Elem;
    std::cout << Elem.GetDOF();
    return 0;
}

To my surprise, the above program compiles and links with Visual Studio 2015 Update 3. I like the idea of allowing alias to be used for explicit template instantiation, but it doesn't seem to work with gcc or clang.

Is it a feature of the forthcoming standard or something specific of VS?

Armen Michaeli
  • 8,625
  • 8
  • 58
  • 95
metalfox
  • 6,301
  • 1
  • 21
  • 43
  • This fails to link with current Clang/C2 (July 2016), but still links with today's daily build (v19.10.24606). Please [file a bug report](https://connect.microsoft.com/VisualStudio/) and post a link to it here. – ildjarn Oct 07 '16 at 14:42
  • 2
    @GuillaumeRacicot In retrospect it's easy to call "stupid" what now is clear was a bad design decision. https://blogs.msdn.microsoft.com/vcblog/2015/09/25/rejuvenating-the-microsoft-cc-compiler/ Yes, VS is non-conforming still, yes, all other major compilers are fully conforming C++14 for a time now. But you have to give credit to them for owning and going (slowly) into the right direction: https://blogs.msdn.microsoft.com/vcblog/2016/06/07/expression-sfinae-improvements-in-vs-2015-update-3/ . They (and us as users) are paying for a mistake made long ago - **that looked right at the time**. – bolov Oct 07 '16 at 14:42
  • @bolov yes you are right. I think I have my load of VS bug for today... – Guillaume Racicot Oct 07 '16 at 14:46
  • @ildjarn I've just tried to submit the bug report but I got a message "You are not authorized to submit the feedback" after loggin in. – metalfox Oct 07 '16 at 14:53
  • 1
    For GCC, you can workaround it by saying `template class FiniteElement2D::FiniteElement` (injected class name). Clang doesn't like that either :) – Johannes Schaub - litb Oct 07 '16 at 14:55
  • @JohannesSchaub-litb I don't think that's valid, grammatically. – Barry Oct 07 '16 at 14:57
  • 2
    @Barry I'm sure it's valid. See http://stackoverflow.com/a/13332744/34509 – Johannes Schaub - litb Oct 07 '16 at 15:02

1 Answers1

1

The answer was given in the comments, but in slightly disguised way, so I will expand it here.

The way MSVC compiler works in this case is almost like doing textual replacement in the program code. It basically replaces all text of FiniteElement2D with FiniteElement<3> - this way the explicit instantiation works fine for you.

Other compilers, on the other hand, build a proper abstract syntax tree for the typedef, and as a result, the alias usage doesn't expand to explicit template instantiation.

As a side note, I am not sure what kind of benefit you expect to get from your syntax.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • 2
    I just happened to do the same syntax in my code as the OP did. Also came across gcc compilation problem after successful compilation in msvc. The benefit is, that it only takes a change in one place (namely the in using declaration) and it will propagate to the explicit template instantiation. Without this approach you need to change it in 2 places. It's almost always cleaner to change in 1 place than in 2. – Marcin K. Oct 20 '20 at 09:17
  • @MarcinK. it can IMO also greatly increase readability (and reduce the risk of doing it wrong) when using mixins, or even worse with CRTP. – Tomáš Kolárik Oct 24 '20 at 13:43