0
template <class C>
C fnc();

template <>
int fnc(){return 0;}

template <class C>
C var;

template <>
int var = 0; // compile error

int main()
{
}

There's a specialization of a fnc function declared without an explicit type indication (such as int fnc<int>()), so the type of template argument is deduced from the function return type, but that thing does not work for variable templates (it leads to compiler error). Is this a correct behavior or a bug in all compilers a have tested (clang, gcc)?

NutCracker
  • 11,485
  • 4
  • 44
  • 68
Denis
  • 2,786
  • 1
  • 14
  • 29
  • 1
    Does this answer your question? [C++14 warning: too many template headers for variable (should be 0)](https://stackoverflow.com/questions/30051718/c14-warning-too-many-template-headers-for-variable-should-be-0) – Algirdas Preidžius Apr 23 '20 at 09:56
  • Next time, please do a search on the "error" to see if the question wasn't asked before, before asking (or at the very least - include it in the question). Note: this is not, technically, an error. – Algirdas Preidžius Apr 23 '20 at 09:58
  • This is not duplicate, because I have interested about conceptual differences between function and variable declarations – Denis Apr 23 '20 at 10:03
  • "_This is not duplicate, because I have interested about conceptual differences between function and variable declarations_" 1) Your question mentions nothing about this. Hence, it is still a duplicate, to a question, as is. 2) The main difference is obvious: one is a function, while other is a variable. – Algirdas Preidžius Apr 23 '20 at 10:04
  • 1
    @user3514538 According to the answer of the linked post, *it can be deduced from the function argument type*, it seems the function template specialization shouldn't work either, it has no arguments. Even I'm not sure why gcc and clang accept it... – songyuanyao Apr 23 '20 at 10:05
  • @Algirdas Preidžius, I saw that answer and a quote from Standard, but there is subject about deduction from function arguments, not from its return value – Denis Apr 23 '20 at 10:05
  • However, std::cout << fnc(); works file, so I guess that this may be a specialization – Denis Apr 23 '20 at 10:09
  • Ok, this is now clear for me why variable specializations can't be compiled without trailing argument, but now it isn't clear why is the function template considered as a specialization by only the return type, but it's already not subject of this topic – Denis Apr 23 '20 at 10:14
  • @songyuanyao I'm also a bit curious as to this. Could it be [\[temp.expl.spec\]/4](https://timsong-cpp.github.io/cppwp/n4659/temp.fct#temp.over.link-4) that applies here? _"When an expression that references a template parameter is used in the function parameter list **or the return type in the declaration of a function template**, the expression that references the template parameter is part of the signature of the function template."_ – dfrib Apr 23 '20 at 10:20
  • @dfri I don't think so, The quote just says the return type refering to template parameter is part of the signature, it doesn't say template parameter could be deduced from return type. Anyway, deducing from return type seems quite counterintuitive to me.. – songyuanyao Apr 23 '20 at 10:24
  • @songyuanyao Curious... Although we still need to explicitly provide the type at the call site (so there is no deduction there), almost as if the standard is referring to a different kind of deduction in the context of _declarations_ of (function) template specializations. – dfrib Apr 23 '20 at 10:42
  • @dfri I have the same feeling too. And yes it's quite counterintuitive that we have to specify the template argument explicitly when calling it but don't need that for specialization, I still think it's not allowed. :) – songyuanyao Apr 23 '20 at 10:48
  • @songyuanyao As I found this both interesting and a bit confusing, I posted [a (follow-up) question](https://stackoverflow.com/questions/61385888/deduction-of-trailing-template-argument-in-declaration-of-explicit-specializatio) on it. – dfrib Apr 23 '20 at 11:15

1 Answers1

1

Template arguments can only be omitted in explicit specialization of function templates. Since you have a template variable, you have to add the <int> part:

template <>
int var<int> = 0;
NutCracker
  • 11,485
  • 4
  • 44
  • 68