如何修复此编译错误:(编译器文件'F:\DD\VCtools\编译器\CXXFE\SL\P1\C\Template.cpp',第 22679 行)?

how to fix this compiling error: (compiler file 'f:ddvctoolscompilercxxfeslp1c emplate.cpp', line 22679)?

本文关键字:编译器 P1 Template cpp 22679 SL DD 错误 编译 文件 VCtools      更新时间:2023-10-16

我在这个问题上很沮丧,Visual Studio 2013就是不满意我的代码(见下文)。我是模板编程的新手,在这个问题上花了很多天,有人可以帮助我吗?

#include <iostream>
#include <utility>
template< typename T, T t >
class Delegate;
template< typename R, typename C, typename... Args, R(C::*F) (Args...)>
class Delegate< R(C::*)(Args...), F > {
public:
    template< typename... Ts >
    static R invoke(Ts&&... args) {
        C t;
        return (t.*F)(std::forward< Ts >(args)...);
    }
};

class Class {
public:
    void print(int v) {
        std::cout << "Class: " << v << std::endl;
    }
};
int main(int argc, char** argv) {
    Delegate< void (Class::*) (int), &Class::print >::invoke(1);
    return 0;
}

编译器给我这些错误信息:

> 1>------ Build started: Project: [test PlatForm]Console,
> Configuration: Release Win32 ------ 1>Build started 2014/8/25
> 10:12:30. 1>C:Program Files
> (x86)MSBuildMicrosoft.Cppv4.0V120Microsoft.CppBuild.targets(356,5):
> warning MSB8004: Intermediate Directory does not end with a trailing
> slash.  This build instance will add the slash as it is required to
> allow proper evaluation of the Intermediate Directory.
> 1>InitializeBuildStatus: 1>  Touching "..intermediate[Test
> Platform]Console[test Pl.B7741A9E.tlogunsuccessfulbuild".
> 1>PreBuildEvent: 1>  SubWCRev: 'E:WorkVC++JustTest' 1>  Last
> committed at revision 77 1>  Updated to revision 77 1>  Local
> modifications found 1>  Unversioned items found 1>ClCompile: 1> 
> Console.cpp 1>  _WIN32_WINNT not defined. Defaulting to
> _WIN32_WINNT_MAXVER (see WinSDKVer.h) 1>Console.cpp(28): fatal error C1001: An internal error has occurred in the compiler. 1>  (compiler
> file 'f:ddvctoolscompilercxxfeslp1ctemplate.cpp', line 22679)
> 1>   To work around this problem, try simplifying or changing the
> program near the locations listed above. 1>  Please choose the
> Technical Support command on the Visual C++  1>   Help menu, or open
> the Technical Support help file for more information 1>         
> Console.cpp(28) : see reference to class template instantiation
> 'Delegate<void (__thiscall Class::* )(int),Class::print>' being
> compiled 1> 1>Build FAILED. 1> 1>Time Elapsed 00:00:00.84
> ========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========

Visual Studio编译器不太支持c++ 11模板。用编译器编译的模板的大多数高级用法会导致内部编译器错误。当涉及到嵌套类型时,VS编译器并没有很好地实现标准。总之,Visual Studio及其编译器不应该与高级c++ 11模板一起使用。上面的解决方案不能修复这个特定的错误。

一个更好的解决方案是不使用Visual Studio编译器。我建议使用与GCC相关的编译器,如MinGW或Cygwin

编辑:我会刮下面的解决方案。我不相信它实际上会工作,因为我发布的错误似乎是与这里不使用的默认参数。您仍然可以尝试使用该解决方案,看看它是否有效。根据评论,下面的解决方案不起作用。我将把它留在那里供将来参考。

这是一个非常特殊的情况,应该通过用static_cast< Ts&& >( args )...代替std::forward< Ts >( args )...来解决。我认为这与模板化结构的使用有关,该结构驻留在专门化类中使用的不同名称空间中。报告的错误可以在这里找到。

可能的解决方法:

template< typename R, typename C, typename... Args>
class Dele
{
public:
   template<R(C::*F)(Args...)>
   struct gate {
    template< typename... Ts >
    static R invoke(Ts&&... args) {
        C t;
        return (t.*F)(std::forward< Ts >(args)...);
    }
   };    
};
int main() {
   Dele<void,Class,int>::gate<&Class::print>::invoke(1);
   return 0;
}

这里的想法是将函数模板参数与参数包分开,我认为这是混淆VS类型系统的原因。这个问题,至少在2013 Express中,似乎是由于其类型系统在试图在这里构造函数指针模板参数时出现错误:

template< typename R, typename C, typename... Args,
              /* --> */ R(C::*F) (Args...) /* <-- */ >

Visual Studio似乎没有在这里展开模板参数包;相反,将其视为等同于R(C::*F)(void);至少在它的部分类型系统中是这样。如果我在print中去掉int参数,一切都对齐了,它神奇地工作了:

class Class {
public:
    void print() {
        std::cout << "Class: " << std::endl;
    }
};

Delegate< void (Class::*) (int), &Class::print >::invoke(1);

如果我使用reinterpret_class来重铸&Class::print,和/或参数,在不同的点,我可以稍微改变错误的位置,直到VS 2013 Express命令行给我相同的错误,你给VS 2013