admin管理员组

文章数量:1355597

When repeating the declaration of a template class with defaulted argument, I get an error:

<source>:12:23: error: redefinition of default argument for 'class<template-parameter-1-2>'
   12 | template <typename T, typename = T>
      |                       ^~~~~~~~
<source>:9:23: note: original definition appeared here
    9 | template <typename T, typename = T>
      |         

Repeating a template forward declaration without default arguments doesn't give any errors. Repeating the same one, but without defaulting the argument also works (but IMO it doesn't make sense and should give some error).
Here's the whole example:

template <typename T>
struct ok;

template <typename T>
struct ok;

template <typename T, typename = T>
struct not_ok;

template <typename T, typename = T>
struct not_ok;

template <typename T, typename = T>
struct why_is_it_ok;

template <typename T, typename>
struct why_is_it_ok;

WHY?

When repeating the declaration of a template class with defaulted argument, I get an error:

<source>:12:23: error: redefinition of default argument for 'class<template-parameter-1-2>'
   12 | template <typename T, typename = T>
      |                       ^~~~~~~~
<source>:9:23: note: original definition appeared here
    9 | template <typename T, typename = T>
      |         

Repeating a template forward declaration without default arguments doesn't give any errors. Repeating the same one, but without defaulting the argument also works (but IMO it doesn't make sense and should give some error).
Here's the whole example:

template <typename T>
struct ok;

template <typename T>
struct ok;

template <typename T, typename = T>
struct not_ok;

template <typename T, typename = T>
struct not_ok;

template <typename T, typename = T>
struct why_is_it_ok;

template <typename T, typename>
struct why_is_it_ok;

WHY?

Share Improve this question asked Mar 31 at 12:36 Sergey KolesnikSergey Kolesnik 3,7272 gold badges14 silver badges44 bronze badges 5
  • to avoid ambiguity (in cases when default type is set to different type). – Marek R Commented Mar 31 at 13:00
  • @MarekR how is it possible to set to a "different" type with the same signature, where the default type is the first one? I'd expect ambiguity when having 2 forward declarations, where only one has a defaulted argument – Sergey Kolesnik Commented Mar 31 at 13:04
  • If you could repeat default type for template parameter, then it would be possible to do template <typename T, typename = int> struct not_ok;. – Marek R Commented Mar 31 at 13:08
  • Also, if you do template <typename T, typename = X> struct not_ok;, there could be a different X visible at different points. In your specific case that is not possible, but there is no exception for the types being the same. You can only give a default value once. – BoP Commented Mar 31 at 13:18
  • 1 That's how default arguments work, template or not. You define each one exactly once per TU. It doesn't matter whether it's a forward declaration or not. You are not allowed to define it twice because then the compiler would have to check whether two mentions are "the same", and before that you would need to define what "the same" means, which is rather non-trivial. Not impossible, but it is much easier to outright disallow it. – n. m. could be an AI Commented Mar 31 at 13:20
Add a comment  | 

1 Answer 1

Reset to default 6

Just like default parameters for function parameters, default parameters for template parameters are only allowed to be set once per scope.

template <typename T>
struct ok;

template <typename T>
struct ok;

Is fine because neither declaration introduces a default parameter.

template <typename T, typename = T>
struct not_ok;

template <typename T, typename = T>
struct not_ok;

Is not allowed because the second unnamed parameter is defaulted twice in the same scope.

template <typename T, typename = T>
struct why_is_it_ok;

template <typename T, typename>
struct why_is_it_ok;

Is allowed because only the first declaration declares a default parameter

本文标签: cError when repeating forward declaration with default template argumentStack Overflow