Equality of int&'s in template parameters
Equality of int&'s in template parameters
Suppose we have the following program:
template <class T, T n1, T n2>
struct Probe {
static const int which = 1;
};
template <class T, T n>
struct Probe<T, n, n> {
static const int which = 2;
};
int i = 123;
const int myQuestion = Probe<int&, i, i>::which;
I am pretty sure, that myQuestion should be 2 regardless of the version of C++ standard, but compilers disagree upon it. MSVC and clang say that it is 2 until C++14, and 1 since C++17. See the demo. What is the truth?
My investigation so far:
K2-Think
The behavior observed is due to changes in how compilers handle non-type template parameters of reference type between C++14 and C++17, particularly regarding the requirements for constant expressions. Here's the breakdown:
Key Issue: Non-Type Reference Template Parameters
The template Probe is defined with a non-type parameter T n1 and T n2, where T can be a reference type (like `int...
GPT-5
Short answer
- C++11/14: myQuestion is 2.
- C++17 and later: myQuestion is 1. Clang and MSVC are correct here; GCC’s “2” in C++17 mode is a bug.
Why it changes in C++17 To see whether the partial specialization
template<class T, T n> struct Probe<T, n, n> { /* ... */ };
matches Probe<int&, i, i>, the standard asks us to “deduce” the template parameters for the partial specialization from th...
o3 Pro
The program
template <class T, T n1, T n2>
struct Probe { // (A)
static const int which = 1;
};
template <class T, T n>
struct Probe<T, n, n> { // (B)
static const int which = 2;
};
int i = 123;
const int myQuestion = Probe<int&, i, i>::which;
instantiates the primary template (A), so myQuestion == 1 accord...
Gemini 2.5 Pro
Excellent question. This is a subtle issue that lies at the intersection of template specialization rules and a significant change to non-type template parameters (NTTPs) in C++17.
The Short Answer
The correct value for myQuestion is 2 in all C++ standards.
The behavior of MSVC and Clang changing from 2 to 1 in C++17 mode is due to a compiler bug. GCC is correct in consisten...
Claude 3.7 Sonnet
Equality of int& in Template Parameters
This question deals with when two non-type template parameters of reference type (int&) are considered equal for template specialization matching.
The Short Answer
According to the C++ standard:
- In C++14 and earlier:
myQuestionshould be 2 - In C++17 and later:
myQuestionshould be 1
The compilers are correct in their behavior. This is a g...
o4 mini
The short answer is: nothing in the standard changed – two non‐type template arguments of reference (or pointer) type are considered identical if they refer to the same entity, and so your partial specialization should be chosen in every C++ mode (myQuestion == 2). GCC has always done the “right” thing here; both clang (and by inheritance MSVC) in C++17 mode are simply non-conforming. A ...
Claude Opus 4
This is a fascinating question about template parameter deduction and specialization matching. Let me analyze what's happening here.
The Core Issue
The key difference between C++14 and C++17 is how non-type template parameters of reference type are handled during template argument deduction and partial specialization matching.
What Changed in C++17
In C++17, there was a significant chang...
DeepSeek R1
Let's break down the code:
template <class T, T n1, T ...
o3
What the standard says
Primary template
template<class T, T n1, T n2> struct Probe { … };
Partial specialization
template<class T, T n> struct Probe<T, n, n> { … };
Instantiation
extern int i; // (has external linkage)
using Q = Probe<int&, i, i>; // what specialization is chosen?
- The three template-arguments that appear in the specializ...
You need to be logged in to submit an answer