C ++二进制表达式的操作数无效

时间:2015-11-10 13:31:58

标签: c++ c++11 enums compilation bitwise-operators

我在C ++ 11中面临一个奇怪的编译错误。

我有一个模板化的类来定义枚举类:

template <typename Type>
class stats {
public:
  // ...
  enum class stat {
    AVERAGE = (1 << 0),
    STANDARD_DERIVATION = (1 << 1),
    // ...
  };
  // ...
};

我目前想在按位操作中使用此枚举。

例如,以下是该枚举的用法示例:

 template <typename Type>
 void
 stats<Type>::build(stat stats) {
     if (stats & stat::AVERAGE)
         this->build_average();

     if (stats & stat::STANDARD_DEVIATION)
         this->build_standard_deviation();

     if (stats & stat::PERCENTILES)
         this->build_percentiles();

     if (stats & stat::LIMITS)
         this->build_limits();
 }

我们可以像这样stats.build(stat::AVERAGE | stat::LIMITS)调用此函数。

为了在枚举上使用&|运算符而不必每次都手动转换为int,我已经定义了运算符:

template<typename T>
using stat_t = typename eip::stats<T>::stat;

template <typename Type>
stat_t<Type>
operator|(const stat_t<Type>& lhs, const stat_t<Type>& rhs) {
  return static_cast<stat_t<Type>>(static_cast<int>(lhs) | static_cast<int>(rhs));
}

template <typename Type>
stat_t<Type>
operator&(const stat_t<Type>& lhs, const stat_t<Type>& rhs) {
    return static_cast<stat_t<Type>>(static_cast<int>(lhs) & static_cast<int>(rhs));
}

但是,如果我尝试编译,我会收到以下错误:

error: invalid operands to binary expression ('eip::stats<double>::stat' and 'eip::stats<double>::stat')
if (stats & stat::PERCENTILES)
    ~~~~~ ^ ~~~~~~~~~~~~~~~~~
candidate template ignored: couldn't infer template argument 'Type'
operator&(const stat_t<Type>& lhs, const stat_t<Type>& rhs) {
^

我不知道为什么忽略了我的超载。似乎编译器为lhs和rhs(eip::stats<double>::stat)得到了正确的类型,但它无法推断模板...

此外:

  • 明确调用运算符(operator&<Type>(stats, stat::AVERAGE);
  • 我认为问题来自返回类型,但调用stat a = stats & stat::AVERAGE;不起作用(与之前的错误相同)。

有什么想法吗?

1 个答案:

答案 0 :(得分:5)

您的代码有两个问题。

  1. 这是一个不可导出的背景:

    async function(){
      return string.replace(regex, async (match)=>{
        let data = await someFunction(match)
        console.log(data); //gives correct data
        return data;
      })
    }
    
    function replaceAsync(str, re, callback) {
        // http://es5.github.io/#x15.5.4.11
        str = String(str);
        var parts = [],
            i = 0;
        if (Object.prototype.toString.call(re) == "[object RegExp]") {
            if (re.global)
                re.lastIndex = i;
            var m;
            while (m = re.exec(str)) {
                var args = m.concat([m.index, m.input]);
                parts.push(str.slice(i, m.index), callback.apply(null, args));
                i = re.lastIndex;
                if (!re.global)
                    break; // for non-global regexes only take the first match
                if (m[0].length == 0)
                    re.lastIndex++;
            }
        } else {
            re = String(re);
            i = str.indexOf(re);
            parts.push(str.slice(0, i), callback.apply(null, [re, i, str]));
            i += re.length;
        }
        parts.push(str.slice(i));
        return Promise.all(parts).then(function(strings) {
            return strings.join("");
        });
    }
    

    这个想法和你写的一样:

    C:\Glassfish\bin>asadmin start-domain
    Waiting for domain1 to start ..........Error starting domain domain1.
    The server exited prematurely with exit code 0.
    Before it died, it produced the following output:
    
    Launching GlassFish on Felix platform
    Registered com.sun.enterprise.glassfish.bootstrap.osgi.EmbeddedOSGiGlassFishRunt
    ime@810a64 in service registry.
    
        #!## LogManagerService.postConstruct : rootFolder=C:\Glassfish\glassfish
        #!## LogManagerService.postConstruct : templateDir=C:\Glassfish\glassfish\lib\te
        mplates
        #!## LogManagerService.postConstruct : src=C:\Glassfish\glassfish\lib\templates\
        logging.properties
        #!## LogManagerService.postConstruct : dest=C:\Glassfish\glassfish\domains\domain1\config\logging.properties
    Completed shutdown of Log manager service
    Completed shutdown of GlassFish runtime
    Nov 10, 2015 1:58:57 PM com.sun.enterprise.glassfish.bootstrap.osgi.BundleProvis
    ioner createBundleProvisioner
    INFORMATION: Create bundle provisioner class = class com.sun.enterprise.glassfis
    h.bootstrap.osgi.BundleProvisioner.
    Nov 10, 2015 1:58:57 PM com.sun.enterprise.glassfish.bootstrap.osgi.BundleProvis
    ioner$DefaultCustomizer getLocations
    WARNUNG: Skipping entry  because it is not an absolute URI.
    Nov 10, 2015 1:58:57 PM com.sun.enterprise.glassfish.bootstrap.osgi.BundleProvis
    ioner$DefaultCustomizer getLocations
    WARNUNG: Skipping entry  because it is not an absolute URI.
    Nov 10, 2015 1:59:01 PM com.sun.enterprise.glassfish.bootstrap.osgi.BundleProvis
    ioner startBundles
    WARNUNG: Can not start bundle file:/C:/Glassfish/glassfish/modules/core.jar beca
    use it is not contained in the list of installed bundles.
    [#|2015-11-10T13:59:04.227+0100|INFO|glassfish 4.1|javax.enterprise.logging|_Thr
    eadID=16;_ThreadName=RunLevelControllerThread-1447160343915;_TimeMillis=14471603
    44227;_LevelValue=800;_MessageID=NCLS-LOGGING-00009;|
      Running GlassFish Version: GlassFish Server Open Source Edition 4.1.1  (build
     1)|#]
    
    [#|2015-11-10T13:59:04.227+0100|INFO|glassfish 4.1|javax.enterprise.logging|_Thr
    eadID=16;_ThreadName=RunLevelControllerThread-1447160343915;_TimeMillis=14471603
    44227;_LevelValue=800;_MessageID=NCLS-LOGGING-00010;|
      Server log file is using Formatter class: com.sun.enterprise.server.logging.OD
    LLogFormatter|#]
    
    [#|2015-11-10T13:59:04.461+0100|INFO|glassfish 4.1|javax.enterprise.system.core.
    security|_ThreadID=18;_ThreadName=RunLevelControllerThread-1447160343946;_TimeMi
    llis=1447160344461;_LevelValue=800;_MessageID=NCLS-SECURITY-01115;|
      Realm [admin-realm] of classtype [com.sun.enterprise.security.auth.realm.file.
    FileRealm] successfully created.|#]
    
    [#|2015-11-10T13:59:04.477+0100|INFO|glassfish 4.1|javax.enterprise.system.core.
    security|_ThreadID=18;_ThreadName=RunLevelControllerThread-1447160343946;_TimeMi
    llis=1447160344477;_LevelValue=800;_MessageID=NCLS-SECURITY-01115;|
      Realm [file] of classtype [com.sun.enterprise.security.auth.realm.file.FileRea
    lm] successfully created.|#]
    
    [#|2015-11-10T13:59:04.477+0100|INFO|glassfish 4.1|javax.enterprise.system.core.
    security|_ThreadID=18;_ThreadName=RunLevelControllerThread-1447160343946;_TimeMi
    llis=1447160344477;_LevelValue=800;_MessageID=NCLS-SECURITY-01115;|
      Realm [certificate] of classtype [com.sun.enterprise.security.auth.realm.certi
    ficate.CertificateRealm] successfully created.|#]
    
    [#|2015-11-10T13:59:04.789+0100|INFO|glassfish 4.1|javax.enterprise.security.ser
    vices|_ThreadID=17;_ThreadName=RunLevelControllerThread-1447160343946;_TimeMilli
    s=1447160344789;_LevelValue=800;_MessageID=SEC-SVCS-00100;|
      Authorization Service has successfully initialized.|#]
    
    [#|2015-11-10T13:59:04.820+0100|INFO|glassfish 4.1|org.hibernate.validator.inter
    nal.util.Version|_ThreadID=15;_ThreadName=RunLevelControllerThread-1447160343915
    ;_TimeMillis=1447160344820;_LevelValue=800;|
      HV000001: Hibernate Validator 5.1.2.Final|#]
    
    [#|2015-11-10T13:59:05.304+0100|INFO|glassfish 4.1|org.glassfish.ha.store.spi.Ba
    ckingStoreFactoryRegistry|_ThreadID=16;_ThreadName=RunLevelControllerThread-1447
    160343915;_TimeMillis=1447160345304;_LevelValue=800;|
      Registered org.glassfish.ha.store.adapter.cache.ShoalBackingStoreProxy for per
    sistence-type = replicated in BackingStoreFactoryRegistry|#]
    
    [#|2015-11-10T13:59:05.335+0100|WARNING|glassfish 4.1|org.glassfish.grizzly.conf
    ig.Utils|_ThreadID=18;_ThreadName=RunLevelControllerThread-1447160343946;_TimeMi
    llis=1447160345335;_LevelValue=900;|
      Instance could not be initialized. Class=interface org.glassfish.grizzly.http.
    server.AddOn, name=http-listener-1, realClassName=org.glassfish.grizzly.http2.Ht
    tp2AddOn|#]
    
    [#|2015-11-10T13:59:05.428+0100|WARNING|glassfish 4.1|org.glassfish.grizzly.conf
    ig.Utils|_ThreadID=18;_ThreadName=RunLevelControllerThread-1447160343946;_TimeMi
    llis=1447160345428;_LevelValue=900;|
      Instance could not be initialized. Class=interface org.glassfish.grizzly.http.
    server.AddOn, name=http-listener-2, realClassName=org.glassfish.grizzly.http2.Ht
    tp2AddOn|#]
    
    [#|2015-11-10T13:59:05.600+0100|INFO|glassfish 4.1|javax.enterprise.system.core|
    _ThreadID=18;_ThreadName=RunLevelControllerThread-1447160343946;_TimeMillis=1447
    160345600;_LevelValue=800;_MessageID=NCLS-CORE-00087;|
      Grizzly Framework 2.3.23 started in: 172ms - bound to [/0.0.0.0:8181]|#]
    
    [#|2015-11-10T13:59:05.600+0100|WARNING|glassfish 4.1|org.glassfish.grizzly.conf
    ig.Utils|_ThreadID=18;_ThreadName=RunLevelControllerThread-1447160343946;_TimeMi
    llis=1447160345600;_LevelValue=900;|
      Instance could not be initialized. Class=interface org.glassfish.grizzly.http.
    server.AddOn, name=admin-listener, realClassName=org.glassfish.grizzly.http2.Htt
    p2AddOn|#]
    
    [#|2015-11-10T13:59:05.616+0100|INFO|glassfish 4.1|javax.enterprise.system.core|
    _ThreadID=18;_ThreadName=RunLevelControllerThread-1447160343946;_TimeMillis=1447
    160345616;_LevelValue=800;_MessageID=NCLS-CORE-00087;|
      Grizzly Framework 2.3.23 started in: 16ms - bound to [/0.0.0.0:4848]|#]
    
    [#|2015-11-10T13:59:05.662+0100|INFO|glassfish 4.1|javax.enterprise.system.core|
    _ThreadID=16;_ThreadName=RunLevelControllerThread-1447160343915;_TimeMillis=1447
    160345662;_LevelValue=800;_MessageID=NCLS-CORE-00087;|
      Grizzly Framework 2.3.23 started in: 0ms - bound to [/0.0.0.0:3700]|#]
    
    [#|2015-11-10T13:59:05.662+0100|INFO|glassfish 4.1|javax.enterprise.system.core|
    _ThreadID=1;_ThreadName=main;_TimeMillis=1447160345662;_LevelValue=800;_MessageI
    D=NCLS-CORE-00017;|
      GlassFish Server Open Source Edition  4.1.1  (1) startup time : Felix (6.974ms
    ), startup services(1.762ms), total(8.736ms)|#]
    
    [#|2015-11-10T13:59:05.662+0100|SEVERE|glassfish 4.1|javax.enterprise.system.cor
    e|_ThreadID=1;_ThreadName=main;_TimeMillis=1447160345662;_LevelValue=1000;_Messa
    geID=NCLS-CORE-00019;|
      Shutting down server due to startup exception
    java.net.BindException: Address already in use: bind
            at sun.nio.ch.Net.bind0(Native Method)
            at sun.nio.ch.Net.bind(Unknown Source)
            at sun.nio.ch.Net.bind(Unknown Source)
            at sun.nio.ch.ServerSocketChannelImpl.bind(Unknown Source)
            at sun.nio.ch.ServerSocketAdaptor.bind(Unknown Source)
            at org.glassfish.grizzly.nio.transport.TCPNIOBindingHandler.bindToChanne
    lAndAddress(TCPNIOBindingHandler.java:131)
            at org.glassfish.grizzly.nio.transport.TCPNIOBindingHandler.bind(TCPNIOB
    indingHandler.java:88)
            at org.glassfish.grizzly.nio.transport.TCPNIOTransport.bind(TCPNIOTransp
    ort.java:248)
            at org.glassfish.grizzly.nio.transport.TCPNIOTransport.bind(TCPNIOTransp
    ort.java:237)
            at org.glassfish.grizzly.nio.transport.TCPNIOTransport.bind(TCPNIOTransp
    ort.java:86)
            at org.glassfish.grizzly.config.GenericGrizzlyListener.start(GenericGriz
    zlyListener.java:184)
            at com.sun.enterprise.v3.services.impl.GlassfishNetworkListener.start(Gl
    assfishNetworkListener.java:109)
            at com.sun.enterprise.v3.services.impl.GrizzlyProxy.start0(GrizzlyProxy.
    java:267)
            at com.sun.enterprise.v3.services.impl.GrizzlyProxy.start(GrizzlyProxy.j
    ava:241)
            at com.sun.enterprise.v3.services.impl.GrizzlyService.createNetworkProxy
    (GrizzlyService.java:567)
            at com.sun.enterprise.v3.services.impl.GrizzlyService.postConstruct(Griz
    zlyService.java:490)
            at org.jvnet.hk2.internal.ClazzCreator.postConstructMe(ClazzCreator.java
    :326)
            at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:374)
            at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:
    471)
            at org.glassfish.hk2.runlevel.internal.AsyncRunLevelContext.findOrCreate
    (AsyncRunLevelContext.java:228)
            at org.glassfish.hk2.runlevel.RunLevelContext.findOrCreate(RunLevelConte
    xt.java:85)
            at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2072)
            at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl
    .java:114)
            at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl
    .java:88)
            at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$QueueRunner.one
    Job(CurrentTaskFuture.java:1213)
            at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$QueueRunner.run
    (CurrentTaskFuture.java:1144)
            at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$UpOneLevel.run(
    CurrentTaskFuture.java:762)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
            at java.lang.Thread.run(Unknown Source)
    |#]
    
    [#|2015-11-10T13:59:05.740+0100|INFO|glassfish 4.1|javax.enterprise.system.core|
    _ThreadID=55;_ThreadName=Thread-11;_TimeMillis=1447160345740;_LevelValue=800;_Me
    ssageID=NCLS-CORE-00092;|
      Server shutdown initiated|#]
    
    [#|2015-11-10T13:59:05.740+0100|INFO|glassfish 4.1|javax.enterprise.bootstrap|_T
    hreadID=1;_ThreadName=main;_TimeMillis=1447160345740;_LevelValue=800;_MessageID=
    NCLS-BOOTSTRAP-00027;|
      Registered com.sun.enterprise.glassfish.bootstrap.osgi.EmbeddedOSGiGlassFishIm
    pl@1aa7d76 as OSGi service registration: org.apache.felix.framework.ServiceRegis
    trationImpl@1a6a933.|#]
    
    [#|2015-11-10T13:59:06.754+0100|INFO|glassfish 4.1|javax.enterprise.bootstrap|_T
    hreadID=55;_ThreadName=Thread-11;_TimeMillis=1447160346754;_LevelValue=800;_Mess
    ageID=NCLS-BOOTSTRAP-00028;|
      Unregistered com.sun.enterprise.glassfish.bootstrap.osgi.EmbeddedOSGiGlassFish
    Impl@1aa7d76 from service registry.|#]
    
    [#|2015-11-10T13:59:06.754+0100|INFO|glassfish 4.1||_ThreadID=55;_ThreadName=Thr
    ead-8;_TimeMillis=1447160346754;_LevelValue=800;|
      FileMonitoring shutdown|#]
    
    [#|2015-11-10T13:59:06.942+0100|INFO|glassfish 4.1|javax.enterprise.system.core|
    _ThreadID=55;_ThreadName=Thread-11;_TimeMillis=1447160346942;_LevelValue=800;_Me
    ssageID=NCLS-CORE-00013;|
      Shutdown procedure finished|#]
    
    Java HotSpot(TM) Client VM warning: ignoring option MaxPermSize=192m; support wa
    s removed in 8.0
    
    Command start-domain failed.
    
    C:\Glassfish\bin>
    

    编译器无法确定template <typename Type> stat_t<Type> operator&(const stat_t<Type>& lhs, const stat_t<Type>& rhs) { ... } 可能存在的内容,除非你也说出来。因此,您必须在我们实际上不需要进行演绎的地方定义您的template <typename T> void foo(typename cls<T>::type ) { ... } :将其作为班级中的朋友操作员:

    T
  2. 一旦我们解决了这个问题,我们就会遇到另一个问题,即operator&无法在上下文中转换为friend stat operator&(const stat& lhs, const stat& rhs) { ... } 所以这个表达式:

    stat

    不会编译。为此,您可能希望让bool返回if (stats & stat::AVERAGE) operator&,或使用this answer的想法,添加int和使用它两次。