Is there a way to write a program so that syntactically it's valid, but when template expansion is done, an error occurs?
Depends on whether your definition of syntactically valid is g++
's -fsyntax-only
or not.
The following simple test program illustrates this and, I believe, answers your question:
// test.cpp
template< bool > struct test;
template< > struct test< true > { };
int main(void) {
test< false > t;
return 0;
}
Attempting to build:
$ g++ /tmp/sa.cpp
test.cpp: In function `int main()':
test.cpp:6: error: aggregate `test< false> t' has incomplete type and
cannot be defined
$ g++ -fsyntax-only /tmp/sa.cpp
test.cpp: In function `int main()':
test.cpp:6: error: aggregate `test< false> t' has incomplete type and
cannot be defined
So yes, -fsyntax-only
does perform template expansion.