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++?
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
or Disabled(/Od)
is not OK./O1
, /O2
and /Ox
are OK./Od
, /O1
, /O2
and /Ox
:-
/Og
is OK./Oi
, /Ot
, /Oy
, /Ob2
, /GF
and /Gy
is not OK.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]
explicit-instantiation:
template declaration
declaration:
block-declaration
block-declaration:
simple-declaration
simple-declaration:
decl-specifier-seq init-declarator-list;
decl-specifier-seq:
decl-specifier
decl-specifier:
defining-type-specifier
defining-type-specifier:
simple-type-specifier
simple-type-specifier:
decltype-specifier
decltype-specifier:
decltype ( expression )
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 well
using F = decltype(foo<int>);
template F foo;
extern template F foo; // not even a definition
Yet it accepts these
F bar;
decltype(foo<int>) baz;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With