Consider the code:
class Test {
public:
template<int N> auto foo() {}
template<> auto foo<0>() { return 7; }
template<int N> void bar() {}
template<> int bar<0>() { return 7; }
};
I have tested the code with different compilers (through Compiler Explorer).
In case of Clang 7.0.0 foo
compiles, while bar
is giving an error:
:8:20: error: no function template matches function template specialization 'bar'
template<> int bar<0>() { return 7; } ^
:7:26: note: candidate template ignored: could not match 'void ()' against 'int ()'
template<int N> void bar() {}; ^
Visual C++ agrees (MSVC 19 2017 RTW):
(8): error C2912: explicit specialization 'int Test::bar(void)' is not a specialization of a function template
gcc 8.2 does not compile any of the code (though the reason is probably a bug in C++17 support:
:5:14: error: explicit specialization in non-namespace scope 'class Test'
template<> auto foo<0>() { return 7; }; ^
:5:28: error: template-id 'foo<0>' in declaration of primary template
template<> auto foo<0>() { return 7; }; ^
:7:26: error: too many template-parameter-lists
template<int N> void bar() {}; ^~~
:8:14: error: explicit specialization in non-namespace scope 'class Test'
template<> int bar<0>() { return 7; } ^
:8:20: error: expected ';' at end of member declaration
template<> int bar<0>() { return 7; } ^~~ ;
:8:23: error: expected unqualified-id before '<' token
template<> int bar<0>() { return 7; } ^
What is the correct interpretation here? Can I have a different return type for different method specializations (and why only with auto
, but not while specifying them explicitly)? With my limited understanding of auto
and templates I would go with saying "no". I don't understand why would using auto
instead of explicitly naming the return type allow to have different return type for different specializations.
However, those codes are simplified versions of the code that I have found elsewhere, so maybe my interpretation is incorrect - and in that case I would be grateful for the explanation why different return type is allowed when auto
is used for specialization, while explicitly naming the type seems to be forbidden.
auto
and explicitly naming the return type in the specialisation. – lukegauto
for specialization when the base template usesauto
and one should name a concrete type when specializing a template that uses a concrete type. It is silent, as far as I can tell, on the issue of changing the return type in specialisation in any of those two cases. As for the second part of your comment (linking stackoverflow.com/questions/2097811/c): my code differs from that in that question because in my code classTest
is not a template, what was a problem in that question. – lukegfoo
is allowed. As for the error withbar
- simply naming the function the same way as a template doesn't mean it's a specialization. You can only specialize the template parameters.int
isn't a template parameter forbar
(but you can make it so, in which case it should work). – Dan M.