首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未命名函数参数

未命名函数参数
EN

Stack Overflow用户
提问于 2014-05-30 17:48:50
回答 4查看 139关注 0票数 1

我正在查看一些与n3960标准提案相关的代码,并注意到一些函数具有没有名称的参数,但有一个完整的函数定义。有人能解释一下这是怎么回事吗?

示例:

代码语言:javascript
复制
template <typename ExPolicy, typename IteratorTag>
void test_for_each(ExPolicy const& policy, IteratorTag) //just IteratorTag, no name?
{
    BOOST_STATIC_ASSERT(hpx::parallel::is_execution_policy<ExPolicy>::value);

    typedef std::vector<std::size_t>::iterator base_iterator;
    typedef test::test_iterator<base_iterator, IteratorTag> iterator;

    std::vector<std::size_t> c(10000);
    std::iota(boost::begin(c), boost::end(c), std::rand());

    hpx::parallel::for_each(policy,
        iterator(boost::begin(c)), iterator(boost::end(c)),
        [](std::size_t& v) {
            v = 42;
        });

    // verify values
    std::size_t count = 0;
    std::for_each(boost::begin(c), boost::end(c),
        [](std::size_t v) {
            HPX_TEST_EQ(v, std::size_t(42));
            ++count;
        });
    HPX_TEST_EQ(count, c.size());
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-05-30 17:57:03

如前所述,参数名是可选的。但为什么忽略了这一点,为什么没有名字的争论呢?

这里使用的技术是基于参数类型的函数模板标记类型推断。

您可以调用传入任意类型实例的test_for_each作为第二个参数。不管该参数的值类型如何,最终都会以IteratorTag的形式传递给IteratorTag函数。

在类中,不使用IteratorTag变量的值--我们只关心类型。

IteratorTag用于区分各种类型的std库迭代器--转发、随机访问、输入、输出等。

有了这种类型,我们就可以对我们的代码的行为方式进行细微的更改(或者使用重载,使代码变得不那么微妙)。在这种情况下,函数中的iterator类型将IteratorTag类型作为其template参数之一,因此该变量的类型根据传入的IteratorTag而有所不同。

下面是一个简单的版本,它使用标记进行一种称为“标记分派”的技术:

代码语言:javascript
复制
template<typename T>
int floor_to_int( T&& t, std::true_type ) { return std::forward<T>(t); }
template<typename T>
int floor_to_int( T&& t, std::false_type ) { return floor(std::forward<T>(t)); }
template<typename T>
int smart_floor( T&& t ) {
  return floor_to_int( std::forward<T>(t), std::is_integral< typename std::decay<T>::type >{} );
}

这里,smart_floor函数接受任意类型的T,当且仅当它是非整数类型时调用它的floor。否则,它只会将其转换为int

我们创建一个标记类型的实例--在本例中是std::is_integral< typename std::decay<T>::type > --并将其传递给内部助手函数。在本例中,我们有两个重载,这两个重载都没有使用传入的标签的值,只使用它的类型。

上述实现类似,但这两种情况下都有1重载。也许该标记类型将以类似的重载方式更深入地使用,或者它在某些特性类中具有更深层次的用途。

这里的论点很可能是std::iterator_traits< T >::iterator_category或一些自制的boost变体,作为旁白。

票数 6
EN

Stack Overflow用户

发布于 2014-05-30 17:52:57

如果实际上不需要参数的值,但必须提供特定的接口,则可以使用未命名的参数。这是沉默(重要的)未使用参数警告的正确方法。

票数 3
EN

Stack Overflow用户

发布于 2014-05-30 17:52:50

在函数原型中,参数名是可选的。它们作为文档可能很有用,但编译器没有以任何有意义的方式使用它们。

在函数定义中,如果函数的正文中没有使用参数,则它的名称也是可选的:

代码语言:javascript
复制
Foo some_function(Bar bar, Baz)
{
    // this is the body of a function that
    // does not use its second argument
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23960593

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档