Ah, I don't think that's a vexing parse issue; it's something else. It's a really great example though, because it illustrates a lot of different issues at once, and I can tell you exactly how you could've avoided it (though a some of the blame does lie with C++). In fact, it's possible you haven't realized what really went wrong yet. What you have (or had, until you used braces) is a heavily-templated version of what simplifies to the following:

struct Instruction { explicit Instruction(int encoding) { } };
using T = Instruction &&;
int encoding = 0;
auto &&result = T(encoding);

There are a few things that went wrong here, but the final red flag to notice is that you should never call a constructor directly with 1 argument directly, because it's just a different syntax for a C-style cast, which we know is dangerous due to its bypassing of safety checks—and this is true regardless of whether we're dealing with C++ constructs (like classes and constructors and such), which I think might be what you're realizing now. (This is poor C++ design, but it's old and people know to avoid them syntactically just like C-style casts. It might be nice to have a warning for it too.) Rather, when you're passing a single argument, you want to write one of these syntaxes:

T result(encoding); // option 1
auto &&result = static_cast<T>(encoding); // option 2

With these, you receive an error, e.g.:

error: invalid static_cast from type 'int' to type 'T' {aka 'Instruction&&'}

I believe this is because the code requires 2 conversions to occur at once, which is an error because (surprise!) it's a generally unsafe thing to do: (a) conversion of int to Instruction, and (b) conversion of Instruction to Instruction&&.

Now you bypassed this by using the uniform initialization syntax (i.e. braces). I'm going to go out on a limb here and say that was another mistake, even though it "solved" your problem here: despite the widespread use, brace initializers are, in my experience, not a good thing, and it's unfortunate that people embraced them (ha) with open arms, and similarly goes with emplace_back() and some other things which I'll address below. The syntactic convenience they provide is just too minor compared to the issues they introduce or obscure. And in this case, they indeed actually introduce a new issue if you use them like 'T result{encoding}': they allow 2 casts to occur at once. I find that incredibly dangerous, and I think it should be at least a warning if not an outright error like before. It seems like a C++ design flaw to me, but in any case, maybe someone should get compiler writers to add a warning for this.

Anyway, let's move on. If you're reading this, you're probably noticing that you ended up with Instruction&& in the first place—that's probably not what you wanted, or at least not what you should've wanted.

And that's where we get to the heart of the issue: your real problem is that you used decltype. If I saw that during code review, I would force you to change it—and using it on declval is just adding more fuel to the ember.

The reality—which unfortunately you do not see people acknowledging—is that decltype, auto, uniform initialization syntax, emplace_back, etc. are all dangerous, and harder to reason about than they look. I think it's unfortunate that the C++ committee encouraged people to use them so much, and I think they're overused to an insane degree. People who love them for their nice syntax don't go out of their way to figure out their pitfalls, but I almost never use any of them unless I absolutely need to. Most problems that they solve (one notable exception being 'auto' with lambdas) were quite elegantly solved in C++03 using typedefs. The only caveat was that you had to give up on the idea of minimizing keystrokes. It's quite a realization when you realize that solves so many of your problems.

Anyway, I'm not trying to blame these on you. Obviously these are blamable on C++, and we could (and should) have more warnings for them. Rather, my main message is that you can avoid these problems (even if they're other people's faults) syntactically—and locally—if you don't try to embrace the absolute "latest and greatest" in C++. IMHO you should only use the newer features if they solve an actual semantic problem for you, not merely because they minimize your typing.

In fact, I think is a huge mistake people make with software in general, and here, C++ in particular. They feel if something is old then it must be bad and you have to do everything in a new way. But if you stick with what works and start caring less about people looking down on you for using "old" syntax just because it's old, you'll find a lot of the old C++03 patterns (typename Pair::first_type, etc.) are actually robust to the problems that the newer ones introduce. People just don't realize this because they're more verbose than they would like, and we're in an era where doing things old style looks bad for no good reason.

Oh also, one last thing: aside from avoiding decltype and using the equivalent of a C-style cast, one more thing that helps you avoid this is to avoid overusing templates. They also obscure what's going on, like here. Not to mention the slow compilation speed and lack of independent compilability. Those are also overused (and I see their appeal) but they're often unnecessary and make code statically difficult to reason about.