问题描述
此代码为run on G++,但为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";
}
这是Visual C ++的错误:-
激励措施::我不想为显式实例化重复函数签名。
我从https://stackoverflow.com/a/28356212修改了代码。
哪个是错的?如何在Visual C ++中解决该问题?
当前的间接解决方法
一天后,这是我发现的最佳解决方法: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>();
但是,在Visual C ++中,它仅在编译foo.cpp
且启用了优化的情况下才起作用:-
-
Custom
或disabled(/Od)
不好。 - 可以全部使用
/O1
,/O2
和/Ox
。 - 没有
/Od
,/O1
,/O2
和/Ox
中的任何一个:-- 只需
/Og
就可以。 - 仅
/Oi
,/Ot
,/Oy
,/Ob2
,/GF
和/Gy
不好。 - 使用上面两行中的所有标志是可以的。
- 只需
解决方法的解决方法(与/Od
一起使用):在.cpp中的伪函数内调用std::tuple_size<decltype(instantiate<int,double>())>
。然后在标头中声明伪函数。
解决方法
我相信msvc是错误的。简而言之,显式实例化只是一个template
后跟您的典型声明。
如果您遵循语法[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 )
我不认为可以解决此问题。显然,msvc将decltype
视为类型别名,并拒绝任何具有别名签名的“感知”定义。这些也被拒绝
using F = decltype(foo<int>);
template F foo;
extern template F foo; // not even a definition
但它接受这些
F bar;
decltype(foo<int>) baz;