首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从msvc v100更新到v140平台工具集时的v100编译错误

从msvc v100更新到v140平台工具集时的v100编译错误
EN

Stack Overflow用户
提问于 2017-06-12 15:13:47
回答 1查看 273关注 0票数 2

我继承了一个必须从MSVC平台工具集v100更新到v140的项目。这是即将发布的Archicad。除了我将平台工具集设置为140之外,所有这些都很好,我的模板函数之一变得疯狂,得到了一个编译错误:

C2064项不计算为带有2个参数的函数

就在这之后,我收到了一条警告:

类不定义使用适当数量参数的“运算符()”或用户定义的将运算符转换为指针到函数或引用到函数的转换运算符。

IDE指出的此块中的返回语句:

代码语言:javascript
复制
template<typename T, typename From>
inline T Convert(From from, const std::locale& locale)
{
    converters::Converter<From, T> conv;
    return conv(from, locale); // <- compilation fails on this line.
}

我有几个类似的专业:

代码语言:javascript
复制
CONVERTER(API_Guid, GS::Guid, from, locale)
{
   (void)locale;    // It gets optimized away
   return APIGuid2GSGuid(from);
}

CONVERTER被定义为:

代码语言:javascript
复制
#define CONVERTER(From, T, from, locale) \
    template<> \
    struct Converter<From, T> : public std::true_type \
    { \
        inline T operator()(const From& from, const std::locale& locale) const; \
    } ;\
    T Converter<From, T>::operator()(const From& from, const std::locale& locale) const

转换器类的operator()重载。我已经尝试过一些解决方法,比如直接定义转换函数,但是这样我就得到了链接器错误。

有人能指出我错过了什么吗?我没有遇到用旧平台工具集编译它的问题。微软在新的版本中改变了什么吗?

我在转换器头上加了沙箱,缩小了范围。标记未注释无法编译的行,并抛出前面提到的编译错误(C2064)。

下面是简化的Convert.hpp:

代码语言:javascript
复制
#pragma once

#include <string>

#include "Declarations.hpp"
#include "utfcpp\utf8.h"

 #define CONVERTER(From, T, from, locale) \
    template<> \
    struct Converter<From, T> : public std::true_type \
    { \
        inline T operator()(const From& from, const std::locale& locale) const; \
    } ;\
    T Converter<From, T>::operator()(const From& from, const std::locale& locale) const

namespace et
{

    template<typename T>
    inline T Convert(const wchar_t* str, const std::locale& locale = std::locale::classic())
    {
        std::wstring wstr(str);
        return Convert<T>(wstr, locale);
    }

    template<typename T, typename From>
    inline T Convert(From from, const std::locale& locale)
    {
        converters::Converter<From, T> conv;
        return conv(from, locale);
    }


    template<typename From>
    inline std::string S(const From& from)
    {
        return Convert<std::string>(from);
    }


    inline std::string S(const wchar_t* from)      
    {
        // return Convert<std::string>(from); <- This line fails to compile on V140, but does on V100
    }

    namespace converters
    {

        template<typename From, typename T, typename _Enabler1, typename _Enabler2, typename _Enabler3>
        struct Converter : _FALSETYPE_
        {
        };

        template<typename From, typename T>
        struct Converter < From, T, _IF_CONVERTIBLE_(From, T) > : _TRUETYPE_
        {
            inline T operator()(const From& from, const std::locale&) const
            {
                return (T)from;
            }
        };

        CONVERTER(std::string, bool, from, locale)
        {
            (void)locale;   // It gets optimized away
            return et::Convert<bool>(from.c_str());
        }


        CONVERTER(bool, std::string, from, locale)
        {
            (void)locale;   // It gets optimized away
            return from ? std::string("true") : std::string("false");
        }

        CONVERTER(std::string, et::UString, s, locale)
        {
            (void)locale;   // It gets optimized away
            et::UString dest;
            utf8::utf8to16(s.begin(), s.end(), std::back_inserter(dest));
            return dest;
        }

        CONVERTER(et::UString, std::string, from, locale)
        {
            (void)locale;   // It gets optimized away
            std::string dest;
            utf8::utf16to8(from.begin(), from.end(), std::back_inserter(dest));

            return dest;
        }

    }
}

如果有人感兴趣的话,下面是更容易复制的Declarations.hpp:

代码语言:javascript
复制
#pragma once

#include <string>

#define _TRUETYPE_  public std::true_type
#define _FALSETYPE_ public std::false_type

#define _IF_CONVERTIBLE_(From, To)  typename std::enable_if<std::is_convertible<From, To>::value>::type
#define _IF_ARITHMETIC_(A)      typename std::enable_if<std::is_arithmetic<A>::value>::type
#define _IF_ARITHMETIC_T_(A, T) typename std::enable_if<std::is_arithmetic<A>::value, T>::type

namespace et
{
    template<typename T, typename Enabler = void, typename Blah = void>
    struct IsConvertibleToString : public std::false_type
    {
    };

    template<typename T>
    struct IsConvertibleToString<T, typename std::enable_if<std::is_convertible<T, std::string>::value>::type > : public std::true_type
    {
    };

    typedef std::u16string UString;

    template<typename T, typename From>
    T Convert(From from, const std::locale& locale = std::locale::classic());

    template<typename From, typename T>
    struct ConvertFunctor;

    namespace converters
    {

        template<typename From, typename To, typename _Enabler1 = void, typename _Enabler2 = void, typename _Enabler3 = void>
        struct Converter;
    }
}

#define _IF_STRING_CONVERTIBLE_(T) typename std::enable_if<::et::IsConvertibleToString<T>::value>::type

从这里可以得到UTF-8CPP:链接.

我仍然对建议感兴趣,但我95%肯定wchar_t是勇气。

EN

回答 1

Stack Overflow用户

发布于 2017-06-12 15:48:10

我想你可能在某个地方错过了一个template<>。

代码语言:javascript
复制
template<>
struct Converter<From, Type> : public std::true_type
{
  inline Type operator()(const From& from, const std::locale& locale) const;
};
// missing template<> here ??  As is, this is not ANSI compliant
Type Converter<From, T>::operator()(const From& from, const std::locale& locale) const { return Type(); }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44502911

复制
相关文章

相似问题

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