【问题标题】:I tried making a class which checks if the number of arguments of a function is valid, but it doesn't work我尝试创建一个类来检查函数的参数数量是否有效,但它不起作用
【发布时间】:2015-09-12 00:27:34
【问题描述】:

这是我编写的代码:

#include <iostream>
#include <algorithm>
template <class T, T(*func)(T ...)> class Foo {
public:
    template <class ...Args> Foo(const Args &...args) {
        func(static_cast<T>(args)...);
    }
};
int main() {
    Foo<int, &std::max>(0, 1);
    return 0;
}

... 如果参数数量无效, Foo::Foo 会抛出错误。 但我得到这个错误:

main.cpp: In function 'int main()':
main.cpp:10:23: error: could not convert template argument '& std::max' to 'int (*)(int, ...)
Foo<int, &std::max>(0, 1);
                  ^

有什么问题?

【问题讨论】:

  • 我不确定我是否理解你想要做什么。编译器已经检查函数的参数数量是否有效。你能澄清一下吗?
  • 我觉得我做的这个“故事”已经足够澄清了:groups.google.com/a/isocpp.org/forum/?fromgroups#!topic/…
  • std::max 是一个函数模板,所以你不能只将它转换为指向函数的指针,你需要一个实际的实例化,比如std::max&lt;int&gt;。您的代码仍然无法编译,因为std::max&lt;int&gt; 的签名不是int(int, ...)
  • 我还是不明白你在做什么。对不起。
  • @Praetorian 将 '&std::max' 更改为 '&std::max' 时仍然出现此错误。

标签: c++ function templates


【解决方案1】:

我解决了一些问题。不知道它是否对你有用,但我们开始吧:

#include <iostream>
#include <algorithm>
template <class T> class Foo {
public:
    template <class ...Args>
    const T& foo(const T & (*func)(const Args& ...), const Args &...args) {
        return func(static_cast<T>(args)...);
    }
};
int main() {
    std::cout << Foo<int>().foo(&std::max<int>, 0, 1);
    return 0;
}

当您执行以下操作时,它实际上会导致编译失败:

Foo<int>().foo(&std::max<int>, 0, 1, 3);

更通用和更好的(恕我直言)解决方案

#include <iostream>
#include <algorithm>

template <class T>
struct Foo {
    template <class ...Args>
    void check(T (func)(Args ...), Args&& ...args) {}
};

// maybe clearer
template<class T, class... Args>
void signatureChecker( T (func)(Args ...), Args&& ...args ) {}

void foo( int i, int x ) {}

int main() {

    int t = 3;
    const int& tt = t;

    // non const version accepts a initializer list
    Foo<int>().check( &std::max<int>, {3,3} );
    Foo<int>().check( &std::max<int>, {tt,3} );
    Foo<const int&>().check( &std::max<int>, tt, tt );
    Foo<void>().check( &foo, 2, 2 );

    signatureChecker<const int&>( &std::max<int>, tt, tt ); 
    signatureChecker<int>( &std::max<int>, {3,3} );

    return 0;
}

另一种直接使用类型而不是参数的解决方案

#include <iostream>
#include <algorithm>

template <class RetType, class... Args>
struct CheckSignature {
    template<RetType(func)(Args...)>
    struct ForFunction {};
};

int main() {
    CheckSignature<const int&, const int&, const int&>
        ::ForFunction<&std::max>();
    return 0;
}

通过所有这些示例和您想要实现的目标的修改,我认为您可以满足您的需求。

【讨论】:

    猜你喜欢
    • 2021-12-04
    • 2012-06-29
    • 1970-01-01
    • 1970-01-01
    • 2017-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多