我遇到了Clang 3.5的問題。以下是一個獨立的repro。此代碼與VC12編譯。鏗鏘我收到以下錯誤:Clang候選模板被忽略:替換失敗(也無法用gcc編譯,VC工作正常)
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.
下面的代碼:
#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;
}
雖然這個例子是相當瑣碎,代碼是一種實用工具庫用於跨DLL邊界封送類型的一大塊。有許多類似的效用函數和針對不同類型的大量專業化。在VC下所有的工作都很好,我懷疑VC接受的只是一些虛假的語法,但是對於Clang和gcc來說,接受它需要稍微更正確。重要的代碼重新排序是困難的,並且系統的重大改寫使用完全不同的方法來專門化轉換函數(例如,撤銷type_traits/enable_if和使用標籤調度或類似)是不切實際的。如果有人可以解釋爲什麼Clang找不到匹配的函數調用util :: details :: out_from_storage(std :: chrono :: system_clock :: time_point &存儲),即使它很清楚存在(並且VC可以找到它)我真的很感激它。我對Clang和gcc非常陌生。謝謝!
請提供[mcve],這裏有很多代碼與您遇到的問題完全無關。 – Barry
N.b. 'util :: details :: template out_from_storage('可以並且應該是'util :: details :: out_from_storage('在兩個地方都有。 – ildjarn
作爲一般規則,如果MSVC不同意GCC和/或clang,MSVC是錯誤的。 – o11c