C++ C++;vararg函数指针

C++ C++;vararg函数指针,c++,variadic-functions,C++,Variadic Functions,以下是否会导致定义良好的行为?也就是说,如果将非vararg函数f强制转换为vararg函数g,并使用f期望的参数调用g,那么调用f的行为是否与使用这些参数调用f的行为相匹配 class Base {}; class Derived1 : public Base { public: int getInt1() {return 1;} }; class Derived2 : public Base { public: int getInt2() {return 2;} };

以下是否会导致定义良好的行为?也就是说,如果将非vararg函数f强制转换为vararg函数g,并使用f期望的参数调用g,那么调用f的行为是否与使用这些参数调用f的行为相匹配

class Base {};

class Derived1 : public Base {
public:
    int getInt1() {return 1;}
};

class Derived2 : public Base {
public:
    int getInt2() {return 2;}
};

typedef int (*vfunc)(...);

int foo (vfunc f) {
    Derived1 d1;
    Derived2 d2;
    return f(&d1, &d2);
}

int bar (Derived1 * p1, Derived2 * p2) {
    return p1->getInt1() + p2->getInt2();
}

int main (int argc, char ** argv) {
    return foo((vfunc)bar); // Is this program guaranteed to return 3?
}
更新

有没有什么方法可以让程序得到良好的定义,即使使用专有关键字?比如做一些像这里提到的
\uu cdecl
之类的事情:


我的最终目标是拥有一个
matcher
函数,该函数尝试在X指针列表上进行匹配。matcher函数接受一个谓词(不一定是一个函数…可能是一个列表)并接受一个它将把匹配结果传递给的函数。传递给它的回调函数采用与匹配谓词相同的参数类型和arity。

否,根据C++11 5.2.11/6(
reinterpret\u cast
),行为未定义:

通过指向与函数定义中使用的类型不同的函数类型的指针调用函数的效果未定义


条的类型为
int(Derived1*,Derived2*)
f
(调用所通过的表达式)指向的函数类型是
int(…)
。两者不相同,因此行为未定义。

否,根据C++11 5.2.11/6(
reinterpret\u cast
),行为未定义:

通过指向与函数定义中使用的类型不同的函数类型的指针调用函数的效果未定义


条的类型为
int(Derived1*,Derived2*)
f
(调用所通过的表达式)指向的函数类型是
int(…)
。两者不一样,因此行为没有定义。

我很确定答案是“不”

例如,在VisualC++中,一个变量函数将具有与普通函数不同的调用约定(当使用<代码>/Gz )时,


调用约定决定生成调用前和调用后的汇编代码,您不能安全地将两者混合使用。

我很确定答案是“否”

例如,在VisualC++中,一个变量函数将具有与普通函数不同的调用约定(当使用<代码>/Gz )时,


调用约定决定了生成什么样的调用前和调用后汇编代码,您不能安全地将两者混合使用。

我相信并期望答案是这是未定义的行为。当您说“专有关键字”时,您的意思是什么?您的目标编译器(以及版本和设置)是什么?您是否愿意接受其他更好的解决方案(如
std::function
)?Visual Studio中的
\uu cdecl
之类的内容。我也对其他解决方案持开放态度。我相信并期望答案是这是未定义的行为。当你说“专有关键字”时,你是什么意思?您的目标编译器(以及版本和设置)是什么?您是否愿意接受其他更好的解决方案(如
std::function
)?Visual Studio中的
\uu cdecl
之类的内容。我也有其他的解决方案。你能解释一下例子中使用的函数的语言链接吗?@K-ballo:抱歉;复制和粘贴是我遇到一些麻烦的技能。我已经更正了引文。您能解释一下示例中使用的函数的语言链接吗?@K-ballo:抱歉;复制和粘贴是我遇到一些麻烦的技能。我已经更正了引文。如果其中一个将调用约定指定为
cdecl
,那么这两种情况会怎样?@K-ballo:你可能会很幸运,但这取决于实现。我不相信C++中有任何规则,编译器必须提供一种方法来指定调用约定。事实上,C++标准很少对调用约定进行说明。(这意味着假设最坏的情况:)如果其中一个将调用约定指定为
cdecl
,那么这两者都会怎么样?@K-ballo:您可能会很幸运,但这取决于实现。我不相信C++中有任何规则,编译器必须提供一种方法来指定调用约定。事实上,C++标准很少对调用约定进行说明。(这意味着假设最坏的情况:)