简体   繁体   English

忽略Clang候选模板:替换失败(也无法使用gcc编译,VC工作正常)

[英]Clang candidate template ignored: substitution failure (also fails to compile with gcc, VC works fine)

I am having an issue with Clang 3.5. 我在使用Clang 3.5时遇到问题。 The following is a self-contained repro. 以下是一个自成体系的副本。 This code compiles with VC12. 此代码使用VC12进行编译。 With Clang I get the following error: 使用Clang我得到以下错误:

1>C:\Users\jcuyle\code\branches\dev\ClientSDK\test\CompilerTestbed\CompilerTestbed.cpp(111,5): error : no matching function for call to 'out_from_storage'
1>          }( util::out_from_storage( rv ) );
1>             ^~~~~~~~~~~~~~~~~~~~~~
1>  C:\Users\jcuyle\code\branches\dev\ClientSDK\test\CompilerTestbed\CompilerTestbed.cpp(37,13):  note: candidate template ignored: substitution failure [with storage_t = std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1, 1000000000> > > &]: no matching function for call to 'out_from_storage'
1>  inline auto out_from_storage( storage_t && storage ) -> decltype( util::details::template out_from_storage( std::forward< storage_t >( storage ) ) )
1>              ^                                                     ~~~~
1>  1 error generated.

Here's the code: 这是代码:

#include <stdint.h>

#include <type_traits>
#include <chrono>
#include <utility>

namespace util
{
namespace details
{

template< typename RTy, typename Ty, typename enable = void >
inline RTy out_from_storage( Ty );

template< typename Ty, typename = typename std::enable_if< std::is_trivial< typename std::decay< Ty >::type >::value, Ty >::type >
inline typename std::add_pointer< typename std::decay< Ty >::type >::type out_from_storage( Ty&& t )
{
    return &t;
}

} // namespace details

template< typename storage_t >
inline auto out_from_storage( storage_t && storage ) -> decltype( util::details::out_from_storage( std::forward< storage_t >( storage ) ) )
{
    return util::details::out_from_storage( std::forward< storage_t >( storage ) );
}

} // namespace util

namespace util
{
namespace details
{

template< typename enable = void >
inline int64_t out_from_storage( std::chrono::system_clock::time_point & storage )
{
    return std::chrono::system_clock::to_time_t( storage );
}

} // namespace details
} // namespace util

int main(int argc, char * argv[])
{
    std::chrono::system_clock::time_point out = std::chrono::system_clock::now( );
    util::out_from_storage( out ); // error
    util::details::out_from_storage( out ); // no error

    return 0;
}

While this example is fairly trivial, the code is a chunk of a utility library for marshaling types across a DLL boundary. 尽管此示例相当简单,但是代码是实用程序库的一部分,用于在DLL边界上封送类型。 There are a number of similar utility functions and a large number of specializations for different types. 有许多类似的实用程序功能,并且有许多针对不同类型的专业化知识。 All works fine under VC, and I suspect there's just some bogus syntax that VC accepts but needs to be slightly more correct for Clang and gcc to accept. 一切在VC下都可以正常工作,我怀疑VC可以接受一些虚假的语法,但是对于Clang和gcc可以接受一些更正确的语法。 Significant reordering of the code is difficult, and major rewrites of the system to use a completely different approach to specializing the conversion functions (eg yanking out the type_traits/enable_if and using tag dispatch or similar) are impractical. 很难对代码进行大幅度的重新排序,并且对系统进行大规模重写以使用完全不同的方法来专门化转换函数(例如取消type_traits / enable_if并使用标签分发或类似方法)是不切实际的。 If someone can explain why it is that Clang can't find the matching function call for util::details::out_from_storage( std::chrono::system_clock::time_point & storage ) even though it pretty clearly exists (and VC can find it) I'd really appreciate it. 如果有人可以解释为什么Clang找不到util :: details :: out_from_storage(std :: chrono :: system_clock :: time_point&storage)的匹配函数调用,即使它很明显存在(并且VC可以找到它)我真的很感激。 I'm very new to Clang and gcc. 我对Clang和gcc非常陌生。 Thanks! 谢谢!

You have one overload of out_from_storage that is callable without explicitly providing template arguments, and it relies on: 您有一个out_from_storage重载,可以在不显式提供模板参数的情况下调用它,并且它依赖于:

std::is_trivial< typename std::decay< Ty >::type >::value

You're calling it with an instance of time_point , but that isn't a trivial type because it doesn't have a trivial default constructor . 您使用time_point实例调用它,但这不是一个普通类型,因为它没有普通的默认构造函数 Hence, this overload is removed from the set. 因此,此过载从集合中移除。

Since there is no viable overload, the call fails. 由于没有可行的过载,因此调用失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 候选模板被忽略:替换失败(clang但不是g ++错误) - candidate template ignored: substitution failure(error with clang but not g++) “忽略候选模板:替换失败:”编译器错误? - "candidate template ignored: substitution failure:" compiler error? clang: 候选模板被忽略: 替换失败: typedef &#39;type&#39; 不能用类说明符引用 - clang: candidate template ignored: substitution failure: typedef 'type' cannot be referenced with a class specifier “候选模板被忽略:替换失败”错误帮助,C ++,犰狳,rank(), - 'candidate template ignored: substitution failure' error help, C++, Armadillo, rank(), 为什么这个代码无法用gcc 4.8.5编译,而它用clang编译好 - Why this code fails to compile with gcc 4.8.5 while it compiles fine with clang 使用enable_if的模板特化在Clang中失败,适用于GCC - Template specialization with enable_if fails in Clang, works with GCC clang上的C ++模板定义失败,适用于GCC - C++ template definition fails on clang, works on GCC 离线构造函数模板在GCC中无法在Clang中运行 - out-of-line constructor template works in GCC fails in Clang clang 3.3中的模板默认Arg替换失败 - Template Default Arg Substitution failure in clang 3.3 可变参数模板适用于 gcc 但不适用于 clang - Variadic template works in gcc but not in clang
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM