如果未实例化成员模板

如果未实例化成员模板

本文介绍了如果未实例化成员模板,是否要评估static_asserts?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以为我了解 static_assert 的工作方式。但是,当我在g ++编译器上尝试此操作时,我开始怀疑:

I'm thought I understood how a static_assert worked. But when I tried this on a g++ compiler, I started to wonder:

#include <iostream>
#include <type_traits>

#define ENABLE_IF(...) std::enable_if_t<__VA_ARGS__, int> = 0

template<typename...Ts>
struct list{};

template<typename...Ts>
struct is_one_of;

template<template <typename...> class TT, typename T, typename T1, typename...Ts>
struct is_one_of<T, TT<T1, Ts...>> : is_one_of<T, TT<Ts...>> {};

template<template <typename...> class TT, typename T, typename...Ts>
struct is_one_of<T, TT<T, Ts...>> : std::true_type {};

template<template <typename...> class TT, typename T>
struct is_one_of<T, TT<>> : std::false_type {};


template<typename...Ts>
struct X;

template<typename P, typename T, typename...Ts>
struct X<P, T, Ts...> : X<P, Ts...>
{
  using X<P, Ts...>::fn;

  template<typename R, ENABLE_IF(std::is_same<T, R>::value)>
  constexpr auto fn(R&& x)
  {
    return x;
  }
};

template<template <typename...> class TT, typename...Ts>
struct X<TT<Ts...>>
{
  template<typename R, ENABLE_IF(!is_one_of<R, TT<Ts...>>::value)>
  constexpr auto fn(R&& x)
  {
    static_assert(false, "Type R didn't match");
  }
};


template<typename...Ts>
struct XX : X<list<Ts...>, Ts...> {};


int main() {
    XX<int, float> x;
    std::cout << x.fn(int(3)) << std::endl;
    return 0;
}

现在我本以为不会有任何基础 X< TT< Ts ...> 类型可以被实例化,因为它从未被调用过。通过这种推理,它不会导致 static_assert 失败。

Now I would have thought that there wouldn't be any way that the base type X<TT<Ts...>> could have ever been instantiated because it is never called. And through this reasoning, it should not cause a static_assert failure.

这在g ++(5.4.0)上失败和clang(3.9.1),但在VC ++ 2015上工作。

This fails on g++ (5.4.0) and clang (3.9.1) but worked on VC++ 2015.

这是缺陷还是我遗漏了某些东西?

Is this a defect or am I missing something?

推荐答案

写 static_assert(false)只是形式不正确,因为它违反了[temp.res]:

Writing static_assert(false) is simply ill-formed, because it runs afoul of [temp.res]:

您可以将其视为-由于 static_assert 的常量表达式不依赖,编译器可以立即看到它是错误的-形成并射击。

You can think of it as - since the static_assert's constant expression isn't dependent, the compiler can just immediately see that it's ill-formed and fire.

您可以不提供 fn()进行该专业化,或者您可以执行以下操作:

You can either just not provide a definition of fn() for that specialization, or you could do something like:

template <class T> struct always_false : std::false_type { };
static_assert(always_false<some_dependent_type>::value, "...");

假设即使没有人可以进行专业化,这也可能产生有效的专业化 always_false 。

This would make it hypothetically possible for a valid specialization to be generated, even if nobody should ever specialize always_false.

这篇关于如果未实例化成员模板,是否要评估static_asserts?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 08:44