具有默认参数的可行函数

时间:2014-12-28 10:28:12

标签: c++ overloading

以下示例在N4296::13.3.3 [over.match.best]

中给出
namespace A 
{
    extern "C" void f(int = 5);
}

namespace B 
{
    extern "C" void f(int = 5);
}

using A::f;
using B::f;

void use() 
{
    f(3); // OK, default argument was not used for viability
    f(); // Error: found default argument twice
}

我试着写类似的东西:

#include <iostream>

namespace A
{
    void foo(int a = 5){ std::cout << a << "1" << std::endl; }
}

namespace B
{
    void foo(int a = 5){ std::cout << a << std::endl; }
}

using A::foo;
using B::foo;

int main()
{ 
    foo(2); //Error 
}

DEMO

但是我遇到了编译时错误。为什么标准说它没问题?

2 个答案:

答案 0 :(得分:3)

区别在于extern“C”,它会影响函数的命名空间成员资格:

来自http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1997/N1138.pdf

  

对于'extern“C”'语言链接,“同一实体”的定义是什么?这是   由7.5节解决:

     

“最多一个具有特定名称的函数可以具有C语言链接。二   具有相同函数名的C语言链接的函数的声明   (忽略限定它的命名空间名称)出现在不同的命名空间范围中   参考相同的功能。具有C语言链接的对象的两个声明   出现在不同的名称(忽略限定它的命名空间名称)   命名空间范围指的是同一个对象。“

答案 1 :(得分:-2)

那是因为这两个函数是从它们的命名空间导入的,这意味着同一个函数有2个定义,你可以这样解决:

#include <iostream>

namespace A
{
    void foo(int a = 5){ std::cout << a << "1" << std::endl; }
}

namespace B
{
    void foo(int a = 5){ std::cout << a << std::endl; }
}

int main()
{ 
    A::foo(2);
    B::foo(3);
}