std :: integral_constant< char *,“kernel32.dll”>将不会编译? [英] std::integral_constant<char*, "kernel32.dll"> won't compile?

查看:164
本文介绍了std :: integral_constant< char *,“kernel32.dll”>将不会编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从char *和kernel32.dll创建整数常量,但总是失败。以下是我的失败尝试,任何人都可以向我显示正确的用法。

 错误1:cout< std :: integral_constant< const char *,kernel32.dll> :: value<< endl; 
error 2:cout<< std :: integral_constant< char *,kernel32.dll> :: value< endl;
error 3:cout<< std :: integral_constant< char [],kernel32.dll> :: value<< endl;
错误4:cout<< cout < std :: integral_constant< char *,static_cast< char *>(kernel32.dll)> :: value< endl;

上述4条语句具有相同的错误信息:

  Console.cpp(181):错误C2762:'std :: integral_constant':无效的表达式作为'_Val'的模板参数
1& D:\Programfiles\Visual Studio 2013\VC\include\xtr1common(35):参见'std :: integral_constant'的声明
1> Console.cpp(181):error C2955:'std :: integral_constant':使用类模板需要模板参数列表
1> D:\Programfiles\Visual Studio 2013\VC\include\xtr1common(35):请参见声明std :: integral_constant
1> Console.cpp(181):warning C4552:'< ;<':operator没有效果;具有副作用的预期运算符

更新:
$ b

std :: integral_constant< std :: string,abc> :: value

结束更新



这里是我的场景,我做一个简单的演示来演示我的目的:

  #include< iostream> 
#include< type_traits>

template<类型名R,类型名C,类型名... Args>
class delegate
{
public:
template< R(C :: * F)(Args ...),typename ... Ts>
struct adapter
{
static R invoke_no_fwd(Args ... args)
{
C t((Ts :: value)...)
return(t。* F)(args ...);
}
};
};

class class
{
public:
Class(const char * psz){
std :: cout< psz < std :: endl;
}
void print(int v)
{
std :: cout< Class:<< v<< std :: endl;
}
};

int main()
{
typedef void(* function_t)(int)
function_t ptrFunc = delegate< void,Class,int> :: adapter<& Class :: print,std :: integral_constant< char *,money> > :: invoke_no_fwd;
auto type = delegate< void,Class,int> :: adapter<& Class :: print,std :: integral_constant< int,42>> :: invoke_no_fwd;
ptrFunc(-42); // 0
type(0); // 42

return 0;
}


解决方案

代码,当前被实例化为 std :: integral_constant<> 只用于访问 :: value static成员,因此您可以用定义 value 成员的任何其他类型替换它,如下所示:

  #include< iostream> 

template< typename T>
void print()
{
std :: cout< (T ::值)< std :: endl;
}

struct X
{
static const char * value;
};

const char * X :: value =ABC;

int main()
{
print< X>();
}

也就是说,只要放入 X 代替 std :: integral_constant<>

  function_t ptrFunc 
= delegate< void,Class,int>
:: adapter<& Class :: print,X / * here!* />
:: invoke_no_fwd;






更新1 b

如果你想在模板实例化中指定字符串的内容,下面的代码会做到:

  template< char ... Chars> 
struct MyString
{
static constexpr char value [] = {Chars ...,'\0'};
};

template< char ... Chars>
constexpr char MyString< Chars ...> :: value [];

// MyString<'A','B','C'> :: value与const char [4] = {ABC}相同;

function_t ptrFunc
= delegate< void,Class,int>
:: adapter<& Class :: print,MyString<'A','B','C'>
:: invoke_no_fwd;

另一个现场演示链接






UPDATE 2
$ b

如果你厌倦了输入 MyString<'k','e','r','n','e','l' ,'2','。','d','l','l'&你可以改为扩展一个原始字符串kernel32.dll code>到符合 MyString< char ...> 模板的逗号分隔字符列表中,使用下面的宏(为简单起见,限制为32个字符 - 长字符串):

  #include< iostream> 

#define STR_1(S,I)(I< sizeof(S)?S [I]:'\0')
#define STR_2 (S,I),STR_1(S,I),STR_1(S,I + 2)
#define STR_4 I)STR_4(S,I),STR_4(S,I),STR_4(S,I + 4)
#define STR_16 STR_32(S,I)STR_16(S,I),STR_16(S,I + 16)
#define STR(S)STR_32(S,0)

template& Chars>
struct MyString
{
static constexpr char value [] = {Chars ...,'\0'};
};

template< char ... Chars>
constexpr char MyString< Chars ...> :: value [];

int main()
{
std :: cout< MyString< STR(kernel32.dll)> :: value<< std :: endl;
}

另一个现场演示链接


I want to make integral constant from char* and "kernel32.dll", but failed always. The following are my failed attempts, anyone can show me the correct usage?

error 1: cout << std::integral_constant<const char*, "kernel32.dll">::value << endl;
error 2: cout << std::integral_constant<char*, "kernel32.dll">::value << endl;
error 3: cout << std::integral_constant<char[], "kernel32.dll">::value << endl;
error 4: cout << cout << std::integral_constant<char*, static_cast<char*>("kernel32.dll")>::value << endl;

the above 4 statements have the same error info.:

Console.cpp(181): error C2762: 'std::integral_constant' : invalid expression as a template argument for '_Val'
1>          D:\Programfiles\Visual Studio 2013\VC\include\xtr1common(35) : see declaration of 'std::integral_constant'
1>Console.cpp(181): error C2955: 'std::integral_constant' : use of class template requires template argument list
1>          D:\Programfiles\Visual Studio 2013\VC\include\xtr1common(35) : see declaration of 'std::integral_constant'
1>Console.cpp(181): warning C4552: '<<' : operator has no effect; expected operator with side-effect

Update:

std::integral_constant<std::string, "abc">::value won't compile either.

end update

Here is my scenario, I make a simple demo to demonstrate my purpose:

#include <iostream>
#include <type_traits>

template< typename R, typename C, typename... Args>
class delegate
{
public:
    template<R(C::*F)(Args...), typename ... Ts>
    struct adapter
    {
        static R invoke_no_fwd(Args... args)
        {
            C t((Ts::value)...);
            return (t.*F)(args...);
        }
    };
};

class Class
{
public:
    Class(const char* psz) {
        std::cout << psz << std::endl;
    }
    void print(int v)
    {
        std::cout << "Class: " << v << std::endl;
    }
};

int main()
{
    typedef void(*function_t)(int);
    function_t ptrFunc = delegate<void, Class, int>::adapter<&Class::print, std::integral_constant<char*, "money"> >::invoke_no_fwd;
    auto type = delegate<void, Class, int>::adapter<&Class::print, std::integral_constant<int, 42>>::invoke_no_fwd;
    ptrFunc(-42); // 0
    type(0); // 42

    return 0;
}

解决方案

The template parameter type in your code, currently instantiated with std::integral_constant<>, is used only to access ::value static member, so you can replace it with any other type defining value member, just like shown below:

#include <iostream>

template <typename T>
void print()
{
    std::cout << (T::value) << std::endl;
}

struct X
{
    static const char* value;
};

const char* X::value = "ABC";

int main()
{
    print<X>();
}

That is, just put X in place of std::integral_constant<>.

function_t ptrFunc
    = delegate<void, Class, int>
          ::adapter<&Class::print, X /*here!*/>
          ::invoke_no_fwd;

Live demo link.


UPDATE 1

If you want to specify the string's content inline, within template instantiation, the below code will do the trick:

template <char... Chars>
struct MyString
{
    static constexpr char value[] = { Chars..., '\0' };
};

template <char... Chars>
constexpr char MyString<Chars...>::value[];

// MyString<'A', 'B', 'C'>::value is same as const char[4] = { "ABC" };

function_t ptrFunc
    = delegate<void, Class, int>
          ::adapter<&Class::print, MyString<'A', 'B', 'C'>>
          ::invoke_no_fwd;

Another live demo link.


UPDATE 2

If you are tired of typing MyString<'k','e','r','n','e','l','3','2','.','d','l','l'> you can instead expand a raw string like "kernel32.dll" into comma-separated characters list compliant with MyString<char...> template, using below macro (that for simplicity is limited to 32-character-long strings):

#include <iostream>

#define STR_1(S,I) (I < sizeof(S) ? S[I] : '\0')
#define STR_2(S,I) STR_1(S,I), STR_1(S,I+1)
#define STR_4(S,I) STR_2(S,I), STR_2(S,I+2)
#define STR_8(S,I) STR_4(S,I), STR_4(S,I+4)
#define STR_16(S,I) STR_8(S,I), STR_8(S,I+8)
#define STR_32(S,I) STR_16(S,I), STR_16(S,I+16)
#define STR(S) STR_32(S,0)

template <char... Chars>
struct MyString
{
    static constexpr char value[] = { Chars..., '\0' };
};

template <char... Chars>
constexpr char MyString<Chars...>::value[];

int main()
{
    std::cout << MyString<STR("kernel32.dll")>::value << std::endl;
}

Yet another live demo link

这篇关于std :: integral_constant&lt; char *,“kernel32.dll”&gt;将不会编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆