提前道歉,我知道评估订单的一般主题已经有很多SO问题.但是,看过它们之后,我想澄清一些我认为不等于重复的具体要点.假设我有以下代码:
#include <iostream>
auto myLambda(int& n)
{
++n;
return [](int param) { std::cout << "param: " << param << std::endl; };
}
int main()
{
int n{0};
myLambda(n)(n);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的程序在编译时输出"n:0".在这里我们有未指定的排序:它可以很容易地输出"n:1"发生了不同的评估顺序.
我的问题是:
在上面的最终函数调用(即lambda表达式调用)中,后缀表达式myLambda(0),其参数n和后续函数调用本身之间的排序关系究竟是什么?
以上是未定义或未指定行为的示例- 以及为什么(参考标准)?
如果我将lambda代码更改为[](int param) { std::cout << "hello" << std::endl }(即使结果独立于其参数,因此任何评估顺序决策,使行为确定性),上述2)的答案是否仍然相同?
编辑:我已将lambda参数名称从'n'更改为'param',因为这似乎导致了混淆.
c++ operator-precedence undefined-behavior language-lawyer c++14
我有以下代码:
#include <iostream>
template <typename T>
struct Base
{
using Type = int;
};
template <typename T>
struct Derived : Base<T>
{
//uncommmenting the below cause compiler error
//using Alias = Type;
};
int main()
{
Derived<void>::Type b = 1;
std::cout << b << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在Type,Derived如果它在推导的上下文中,则可以使用typename - 如完全有效的声明所示b.但是,如果我尝试Type在其Derived自身的声明中引用,那么我得到一个编译器错误告诉我Type没有命名类型(例如,如果Alias取消注释的定义).
我想这与编译器Type在解析Derived参数的特定实例化的上下文之外的定义时无法检查是否可以从基类中引入时有关T.在这种情况下,这是令人沮丧的,因为Base 总是定义Type不论T.所以我的问题是双重的:
1).为什么地球会发生这种情况?通过这个我的意思是为什么编译器 …
假设我有一个带有模板模板参数的函数,如下所示:
template <template <class T> class F, typename P>
void applyFunction(int param)
{
F<P> fn;
fn(param);
}
Run Code Online (Sandbox Code Playgroud)
以上可以为 Functor 获取任意类模板并应用它。例如,如果我定义:
template<typename T>
struct SomeFunctor
{
void operator()(int param)
{
T::doStuff(param);
}
};
Run Code Online (Sandbox Code Playgroud)
然后我可以拨打以下电话:
applyFunction<SomeFunctor, MyClass>(0);
Run Code Online (Sandbox Code Playgroud)
但我真正想做的是能够传递函数模板(而不仅仅是定义函子的类模板)。所以如果我有这样的事情:
template<typename T>
void someFunction(int param)
{
T::doStuff(param);
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,我可以做这样的事情:
applyFunction<someFunction, MyClass>(0);
Run Code Online (Sandbox Code Playgroud)
不幸的是,目前这不是合法的 C++。有没有办法做到这一点,我失踪了?换句话说,传递函数模板而不是类模板作为模板模板参数?从概念上讲,我不明白为什么它不应该是可能的。
请考虑以下代码(以下问题):
#include <iostream>
struct Type0
{
Type0(char* c)
{}
};
struct Type1
{
Type1(int* i=nullptr) : i_(i)
{}
Type1(const Type1& other) = default;
int* i_;
};
template <typename ...>
struct Composable;
template <typename T0, typename ... T>
struct Composable<T0, T...> : T0, Composable<T...>
{
Composable()
{
std::cout << "Default Invoked: " << sizeof...(T) << std::endl;
}
Composable(const Composable& other) = default;
template<typename Arg, typename ... Args>
Composable(Arg&& arg, Args&& ... args) :
T0(std::forward<Arg>(arg)), Composable<T...>(std::forward<Args>(args)...)
{
std::cout << "Non-default invoked: " …Run Code Online (Sandbox Code Playgroud)