C++ 如果没有实例化成员模板,是否要评估静态_断言?
我想我明白了一个静态的断言是如何工作的。但当我在g++编译器上尝试这一点时,我开始怀疑:C++ 如果没有实例化成员模板,是否要评估静态_断言?,c++,c++14,C++,C++14,我想我明白了一个静态的断言是如何工作的。但当我在g++编译器上尝试这一点时,我开始怀疑: #include <iostream> #include <type_traits> #define ENABLE_IF(...) std::enable_if_t<__VA_ARGS__, int> = 0 template<typename...Ts> struct list{}; template<typename...Ts> stru
#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,因为它从未被调用过。通过这种推理,它不应该导致静态错误
这在g++5.4.0和clang 3.9.1上失败,但在VC++2015上有效
这是一个缺陷还是我遗漏了什么?编写static\u assertfalse完全是格式错误,因为它与[temp.res]冲突:
如果出现以下情况,程序格式不正确,无需诊断:
-如果模板中的语句6.4.1且模板未实例化,则无法为模板或constexpr的子状态生成有效的专门化
您可以将其视为-因为static_assert的常量表达式是不依赖的,编译器可以立即看到它的格式不正确并触发
您可以不为该专门化提供fn的定义,也可以执行以下操作:
template <class T> struct always_false : std::false_type { };
static_assert(always_false<some_dependent_type>::value, "...");
这将使一个有效的专门化假设成为可能,即使没有人应该专门化总是错误的 编写static_assertfalse完全是格式错误的,因为它与[temp.res]相冲突:
如果出现以下情况,程序格式不正确,无需诊断:
-如果模板中的语句6.4.1且模板未实例化,则无法为模板或constexpr的子状态生成有效的专门化
您可以将其视为-因为static_assert的常量表达式是不依赖的,编译器可以立即看到它的格式不正确并触发
您可以不为该专门化提供fn的定义,也可以执行以下操作:
template <class T> struct always_false : std::false_type { };
static_assert(always_false<some_dependent_type>::value, "...");
这将使一个有效的专门化假设成为可能,即使没有人应该专门化总是错误的