作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个方法 fun
包含在结构 Impl
中用于部分特化。检查 is_derived_from_template
用于确定泛型 Impl::fun
是否可用于派生自特定模板的类型。否则,Impl
是显式部分特化的。
#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;
^
但是,clang 没有错误地编译它并且输出符合预期:
Foo
Base
最佳答案
减少到
#include <utility>
void f(...);
class C;
using type = decltype(f(std::declval<C>()));
在 Clang 上编译,在 GCC 上出错。
我倾向于说 GCC 就在这里,因为通过 ...
传递一个类类型的对象需要复制,而你不能复制类型不完整的东西。
如果您愿意,可以在 SFINAE 中使用指针:
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;
};
虽然您应该谨慎允许 is_derived_from_template
以不完整的类型实例化,因为如果完整的类型结果是从指定模板派生的,它很容易导致 ODR 违规。
关于c++ - gcc vs. clang: "invalid use of incomplete type"with std::declval 和模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34810614/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
正如您在 this travis.yml 中看到的那样文件,我的代码依赖于一些第三方库,我在构建项目之前将它们安装在远程系统上。 Travis 每次推送提交时都会下载并构建这些库,这可以避免吗?我的意
我是一名优秀的程序员,十分优秀!