首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试为对象属性(成员变量)使用C++自动类型并推导出std::bind的返回类型时出现问题

尝试为对象属性(成员变量)使用C++自动类型并推导出std::bind的返回类型时出现问题
EN

Stack Overflow用户
提问于 2020-12-16 10:29:55
回答 1查看 82关注 0票数 2

我有下面的代码,它试图生成一个随机的十六进制数字。

代码语言:javascript
复制
#include <random>
#include <functional>


using std::mt19937;
using std::uniform_int_distribution;


class
RandomHexDigitGenerator
(
    public :

        // Other functions omitted for the sake of brevity.

        RandomHexDigitGenerator
        (
        );

        char
        generateRandomHexDigit
        (
        );


    private :

        mt19937                       * rng_p;

        mt19937::result_type            seed;

        uniform_int_distribution<int> * distribution_p;  // Map values onto range [0, 15]

        // The following declaration will cause a problem since
        // the compiler won't be able to deduce its type.

        auto                            rhvg;
);

其中两种方法的定义如下;

代码语言:javascript
复制
// Constructor for class.

RandomHexDigitGenerator::RandomHexDigitGenerator
(
)
{
    this->seed           = time(0);

    this->rng_p          = new mt19937(this->seed);

    this->distribution_p = new uniform_int_distribution<int>(0, 15);

    // The following line of code will also be problematic.

    this->rhvg           = std::bind(* this->distribution_p, * this->rng_p);
}


char
RandomHexDigitGenerator::generateRandomHexDigit
(
)
{
    int   randomHexValue;


    randomHexValue = this->rhvg();

    return(this->convertHexValueToHexDigit(randomHexValue));
}

我的问题是代码中的绑定操作是在构造函数中执行的。我不知道它的返回类型是什么,这就是为什么我将rhvg声明为auto。问题是-根据我的理解,编译器需要能够在第一次在类声明中遇到rhvg时推断出它的类型!

所以我的问题是,我该如何解决这个问题?绑定操作返回的类型会不会很可怕,因此我甚至不应该费心去弄清楚它是什么?我是否应该继续使用自动,但以另一种方式?模板化类是一种选择,还是模板化一个复杂的解决方案来解决一个不那么困难的问题?

如果重要的话,我在Linux Mint19.2版本下使用GNU g++,g++ -v命令的输出如下所示;

代码语言:javascript
复制
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.10' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10)

最后,我的Makefile在正确的位置使用了-std=c++11编译器开关。

提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-17 15:25:04

你的代码比我所熟悉的更加复杂和冗长。这就是我要做的:

代码语言:javascript
复制
#include <random>
#include <ctime>
    
class RandomHexDigitGenerator
{
  public:
    char generateRandomHexDigit() {
        return static_cast<char>(dist(rng));
    }
  private:
    std::mt19937 rng{static_cast<std::mt19937::result_type>(std::time(0))};
    std::uniform_int_distribution<int> dist{0, 15};
};

没有new,就没有bind

返回到所提出的问题,您不能拥有“未知绑定结果”类型的非静态类成员。您可以使用std::function,但这没有任何意义,原因如下。

bind通过复制来存储其参数,因此如果您这样做

代码语言:javascript
复制
std::function<char(void)> rhvg;
rhvg = std::bind(distribution, rng);

您不再需要distributionrng成员,因为它们被复制到bind。因此,您可以在构造函数中创建它们。

代码语言:javascript
复制
class RandomHexDigitGenerator
{
  public:
    char generateRandomHexDigit() {
       return rhvg();
    }
  private:
    std::function<char(void)> rhvg = std::bind(
      std::uniform_int_distribution<int>(0, 15),
      std::mt19937(static_cast<std::mt19937::result_type>(std::time(0)))
    );
};

但是为什么要有一个这样的类呢?您可以将所有内容包装在一个函数中:

代码语言:javascript
复制
std::function<char(void)> makeRandomHexDigitGenerator() {
  return std::bind(whatever);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65316471

复制
相关文章

相似问题

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