11

此代码在 G++ 上运行,但不在 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>();

foo.cpp但是,在 Visual C++ 中,它仅在打开优化进行编译时才有效:-

  • Custom或者Disabled(/Od)不行。
  • 全部使用/O1/O2/Ox OK了。
  • 没有任何/Od, /O1,/O2/Ox:-
    • 刚刚/Og好。
    • 只是/Oi, /Ot, /Oy, /Ob2, /GFand/Gy是不行的。
    • 使用上面两行中的所有标志就可以了。

变通方法的变通方法(使用/Od):std::tuple_size<decltype(instantiate<int, double>())>在 .cpp 中调用内部虚拟函数。然后在头文件中声明虚拟函数。

4

1 回答 1

1

我相信 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;
于 2020-09-21T11:29:55.613 回答