我有一個方法fun
它包含在結構Impl
部分專業化。檢查is_derived_from_template
用於確定通用Impl::fun
是否可用於類型,如果它是從特定模板派生的。否則,Impl
部分專門明確。gcc與clang:「std :: declval和模板特化的無效使用不完整類型」
#include <iostream>
template <typename T, typename U>
struct Base{};
// Forward declaration
struct Foo;
struct Bar;
template <template<typename...> class T, typename U>
struct is_derived_from_template
{
private:
template<typename... Args>
static decltype(static_cast<const T<Args...>&>(std::declval<U>()), std::true_type{}) test(const T<Args...>&);
static std::false_type test(...);
public:
static constexpr bool value = decltype(test(std::declval<U>()))::value;
};
template <typename T, typename = void>
struct Impl
{
static void fun(T& x);
};
template <typename T>
struct Impl<T, typename std::enable_if<is_derived_from_template<Base, T>::value>::type>
{
static void fun(T& base)
{
std::cout << "Base" << std::endl;
}
};
template <>
void Impl<Foo>::fun(Foo& t)
{
std::cout << "Foo" << std::endl;
}
struct Foo {};
struct Bar : Base<int,double> {};
int main()
{
Foo foo;
Bar bar;
Impl<Foo>::fun(foo);
Impl<Bar>::fun(bar);
}
當編譯這個代碼用gcc,我得到以下錯誤:
main.cpp: In instantiation of 'constexpr const bool is_derived_from_template<std::vector, Foo>::value':
main.cpp:33:15: required from here
main.cpp:15:48: error: invalid use of incomplete type 'struct Foo'
static constexpr bool value = decltype(test(std::declval<U>()))::value;
^
main.cpp:5:8: note: forward declaration of 'struct Foo'
struct Foo;
^
然而,鐺編譯這沒有錯誤,如預期的輸出:
Foo
Base
- 這兩個編譯器中哪一個是對的?
- 如何修改我的代碼以使其與gcc一起使用?