是否未指定在未评估的上下文中实例化模板/lambda
Is it unspecified to instantiate template/lambda in unevaluated context?
我尝试以下代码检查模板是否在未评估的上下文中实例化:
#include "foo.h"
template <typename T = int>
constexpr auto f(int)
// from declaration, foo(std::declval<T>()) is allowed.
// Even if definition would produce errors if instantiated
-> decltype(foo(std::declval<T>()), void(), 42)
{
return 42;
}
static_assert(f(0) == 42);
使用foo
作为模板函数:(无错误(
template <typename ...Ts>
void foo(Ts... args)
{
static_assert(sizeof...(Ts) == 42, "!");
((args += ""), ...);
}
演示
用foo
作为常规函数:(无错误(
struct Foo
{
template <typename ...Ts>
void operator ()(Ts... args) const
{
static_assert(sizeof...(args) == 42, "!");
((args += ""), ...);
}
} foo;
演示
但是 foo
as lambda :(错误(
auto foo = [](auto... args)
{
static_assert(sizeof...(args) == 42, "!"); // Triggers
((args += ""), ...); // spotted as invalid: int += const char*
};
演示
lamdba的operator()
实例化是否正常?
GCC/clang具有相同的行为。
lambda情况实际上与其他情况不同!您没有为lambda指定返回类型,因此可以推导它。为了扣除,必须实例化lambda。
函数对象不是这种情况,因为您指定返回类型为 void
。更改Lambda以返回void
以避免扣除使GCC/Clang快乐。:(
auto foo = [](auto... args) -> void // <---
{
static_assert(sizeof...(args) == 42, "!");
((args += ""), ...);
};
,如果您更改函数对象如下:
struct Foo
{
template <typename ...Ts>
auto operator ()(Ts... args) const // <---- placeholder as return type
{
static_assert(sizeof...(args) == 42, "!");
((args += ""), ...);
}
} foo;
它也确实实例化了Foo::operator()
,以推断出返回类型。
相关文章:
- 从C++实例化QML
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 约束和显式模板实例化
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 对象实例化调用构造函数的次数太多
- 如何使用非默认构造函数实例化模板化类
- 静态数据成员模板专用化的实例化点在哪里
- 错误的cv::face FacemarkLBF实例化
- C++的解析器在可以区分比较和模板实例化之前会做什么?
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 是否未指定在未评估的上下文中实例化模板/lambda
- Lambda构造函数中的实例化
- 模板,lambda作为每个实例化的唯一默认参数
- C++-为任何lambda创建一个实例化桶
- 在泛型lambda表达式的所有实例化之间共享的局部静态变量
- 按类型实例化C++ lambda
- 如何将lambda函数传递给带有模板类的类实例化
- 由于抽象模板arg的实例化,Boost::lambda表达式编译失败.任何解释和/或解决方法