This codes run on G++, but not on Visual C++.
#include <iostream>
template<typename T> void foo( T& t,int some_parameter){}
template decltype(foo<int>) foo;
int main(){
std::cout << "Hello, world!\n";
}
Here is the error from Visual C++ :-
error C2206: 'foo': typedef cannot be used for function definition
Incentive : I don't want to repeat function signature for explicit instantiation.
I modified code from https://stackoverflow.com/a/28356212 .
Which one is wrong? How to workaround it in Visual C++?
Current indirect workaround
A day later, here is the best workaround I found : https://stackoverflow.com/a/50350144 .
#include <tuple>
template<typename... Ts>auto instantiate() {
static auto funcs = std::tuple_cat(std::make_tuple(
foo1<Ts>,
foo2<Ts>
)...);
return &funcs;
}
template auto instantiate<int, double>();
However, in Visual C++, it works only when compile foo.cpp
with optimization turned on :-
Custom
orDisabled(/Od)
is not OK.- Use all of
/O1
,/O2
and/Ox
are OK. - Without any of
/Od
,/O1
,/O2
and/Ox
:-- Just
/Og
is OK. - Just
/Oi
,/Ot
,/Oy
,/Ob2
,/GF
and/Gy
is not OK. - Use all flags in the two above lines is OK.
- Just
Workaround of the workaround (work with /Od
): Call the std::tuple_size<decltype(instantiate<int, double>())>
inside a dummy function in a .cpp. Then declare the dummy function in header.
I believe msvc is wrong. In short, an explicit instantiation is simply a
template
followed by your typical declaration.If you follow the grammar [temp.explicit]
I don't believe there is a work around for this. Apparently, msvc considers
decltype
as a type alias, and rejects any "perceived" definitions with signatures that are aliases. These are rejected as wellYet it accepts these