10
Stack Exchange
votes

Equality of int&'s in template parameters

Posted on 2/7/2022
UQ ID:390
Technology
Stack Overflow
Original

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:

  • I have found one relevant sentence in the C++ standard. It was there in C++11, C++14, C++17 and C++20. It did not change.
  • If you remove the parameter T from the example code, all compilers agree, that myQuestion is 2. Demo.
Keywords & Tags
c++
c++17
c++14
template-specialization
non-type-template-parameter
Model Answers (9)
Submitted answers from various AI models
Unsolved
No reviews yet

K2-Think

Pending UQ Validation
Needs Human Verification
MBZUAI-IFM
Qwen2.5-32B
Sep 18, 2025, 01:50 PM

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...

0 model reviews
0 human reviews
No reviews yet

GPT-5

Failed UQ Validation
Needs Human Verification
OpenAI
Sep 2, 2025, 06:56 AM

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...

0 model reviews
0 human reviews
No reviews yet

o3 Pro

Failed UQ Validation
Needs Human Verification
OpenAI
Aug 1, 2025, 12:00 AM

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...

0 model reviews
0 human reviews
No reviews yet

Gemini 2.5 Pro

Failed UQ Validation
Needs Human Verification
Google
Aug 1, 2025, 12:00 AM

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...

0 model reviews
0 human reviews
No reviews yet

Claude 3.7 Sonnet

Failed UQ Validation
Needs Human Verification
Anthropic
Aug 1, 2025, 12:00 AM

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: myQuestion should be 2
  • In C++17 and later: myQuestion should be 1

The compilers are correct in their behavior. This is a g...

0 model reviews
0 human reviews
No reviews yet

o4 mini

UQ Validated
Needs Human Verification
OpenAI
Aug 1, 2025, 12:00 AM

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 ...

0 model reviews
0 human reviews
No reviews yet

Claude Opus 4

Failed UQ Validation
Needs Human Verification
Anthropic
Aug 1, 2025, 12:00 AM

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...

0 model reviews
0 human reviews
No reviews yet

DeepSeek R1

Failed UQ Validation
Needs Human Verification
DeepSeek
deepseek-ai/DeepSeek-R1
Aug 1, 2025, 12:00 AM
<think> We are given a program that uses template specialization and non-type template parameters. The question is about the value of `myQuestion` which is set to `Probe<int&, i, i>::which`. The user expects it to be 2 (using the partial specialization) but notes that compilers (MSVC and Clang) change behavior between C++14 and C++17.

Let's break down the code:

template <class T, T n1, T ...
0 model reviews
0 human reviews
No reviews yet

o3

Failed UQ Validation
Needs Human Verification
OpenAI
Aug 1, 2025, 12:00 AM

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?
  1. The three template-arguments that appear in the specializ...
0 model reviews
0 human reviews
Submit Your Model's Answer
Your submission will be validated by our LLM validator and then by human experts

You need to be logged in to submit an answer