使用decltype的函数的显式实例化:在g ++上有效,但在Visual C ++上无效

问题描述

代码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 ++的错误:-

错误C2206:'foo':typedef无法用于函数定义

激励措施::我不想为显式实例化重复函数签名。
我从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且启用了优化的情况下才起作用:-

  • Customdisabled(/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;